+++ /dev/null
- GNU GENERAL PUBLIC LICENSE
- Version 2, June 1991
-
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.
- 675 Mass Ave, Cambridge, MA 02139, USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
- Preamble
-
- The licenses for most software are designed to take away your
-freedom to share and change it. By contrast, the GNU General Public
-License is intended to guarantee your freedom to share and change free
-software--to make sure the software is free for all its users. This
-General Public License applies to most of the Free Software
-Foundation's software and to any other program whose authors commit to
-using it. (Some other Free Software Foundation software is covered by
-the GNU Library General Public License instead.) You can apply it to
-your programs, too.
-
- When we speak of free software, we are referring to freedom, not
-price. Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it
-in new free programs; and that you know you can do these things.
-
- To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if you
-distribute copies of the software, or if you modify it.
-
- For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must give the recipients all the rights that
-you have. You must make sure that they, too, receive or can get the
-source code. And you must show them these terms so they know their
-rights.
-
- We protect your rights with two steps: (1) copyright the software, and
-(2) offer you this license which gives you legal permission to copy,
-distribute and/or modify the software.
-
- Also, for each author's protection and ours, we want to make certain
-that everyone understands that there is no warranty for this free
-software. If the software is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original, so
-that any problems introduced by others will not reflect on the original
-authors' reputations.
-
- Finally, any free program is threatened constantly by software
-patents. We wish to avoid the danger that redistributors of a free
-program will individually obtain patent licenses, in effect making the
-program proprietary. To prevent this, we have made it clear that any
-patent must be licensed for everyone's free use or not licensed at all.
-
- The precise terms and conditions for copying, distribution and
-modification follow.
-\f
- GNU GENERAL PUBLIC LICENSE
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
- 0. This License applies to any program or other work which contains
-a notice placed by the copyright holder saying it may be distributed
-under the terms of this General Public License. The "Program", below,
-refers to any such program or work, and a "work based on the Program"
-means either the Program or any derivative work under copyright law:
-that is to say, a work containing the Program or a portion of it,
-either verbatim or with modifications and/or translated into another
-language. (Hereinafter, translation is included without limitation in
-the term "modification".) Each licensee is addressed as "you".
-
-Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope. The act of
-running the Program is not restricted, and the output from the Program
-is covered only if its contents constitute a work based on the
-Program (independent of having been made by running the Program).
-Whether that is true depends on what the Program does.
-
- 1. You may copy and distribute verbatim copies of the Program's
-source code as you receive it, in any medium, provided that you
-conspicuously and appropriately publish on each copy an appropriate
-copyright notice and disclaimer of warranty; keep intact all the
-notices that refer to this License and to the absence of any warranty;
-and give any other recipients of the Program a copy of this License
-along with the Program.
-
-You may charge a fee for the physical act of transferring a copy, and
-you may at your option offer warranty protection in exchange for a fee.
-
- 2. You may modify your copy or copies of the Program or any portion
-of it, thus forming a work based on the Program, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
- a) You must cause the modified files to carry prominent notices
- stating that you changed the files and the date of any change.
-
- b) You must cause any work that you distribute or publish, that in
- whole or in part contains or is derived from the Program or any
- part thereof, to be licensed as a whole at no charge to all third
- parties under the terms of this License.
-
- c) If the modified program normally reads commands interactively
- when run, you must cause it, when started running for such
- interactive use in the most ordinary way, to print or display an
- announcement including an appropriate copyright notice and a
- notice that there is no warranty (or else, saying that you provide
- a warranty) and that users may redistribute the program under
- these conditions, and telling the user how to view a copy of this
- License. (Exception: if the Program itself is interactive but
- does not normally print such an announcement, your work based on
- the Program is not required to print an announcement.)
-\f
-These requirements apply to the modified work as a whole. If
-identifiable sections of that work are not derived from the Program,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works. But when you
-distribute the same sections as part of a whole which is a work based
-on the Program, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Program.
-
-In addition, mere aggregation of another work not based on the Program
-with the Program (or with a work based on the Program) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
- 3. You may copy and distribute the Program (or a work based on it,
-under Section 2) in object code or executable form under the terms of
-Sections 1 and 2 above provided that you also do one of the following:
-
- a) Accompany it with the complete corresponding machine-readable
- source code, which must be distributed under the terms of Sections
- 1 and 2 above on a medium customarily used for software interchange; or,
-
- b) Accompany it with a written offer, valid for at least three
- years, to give any third party, for a charge no more than your
- cost of physically performing source distribution, a complete
- machine-readable copy of the corresponding source code, to be
- distributed under the terms of Sections 1 and 2 above on a medium
- customarily used for software interchange; or,
-
- c) Accompany it with the information you received as to the offer
- to distribute corresponding source code. (This alternative is
- allowed only for noncommercial distribution and only if you
- received the program in object code or executable form with such
- an offer, in accord with Subsection b above.)
-
-The source code for a work means the preferred form of the work for
-making modifications to it. For an executable work, complete source
-code means all the source code for all modules it contains, plus any
-associated interface definition files, plus the scripts used to
-control compilation and installation of the executable. However, as a
-special exception, the source code distributed need not include
-anything that is normally distributed (in either source or binary
-form) with the major components (compiler, kernel, and so on) of the
-operating system on which the executable runs, unless that component
-itself accompanies the executable.
-
-If distribution of executable or object code is made by offering
-access to copy from a designated place, then offering equivalent
-access to copy the source code from the same place counts as
-distribution of the source code, even though third parties are not
-compelled to copy the source along with the object code.
-\f
- 4. You may not copy, modify, sublicense, or distribute the Program
-except as expressly provided under this License. Any attempt
-otherwise to copy, modify, sublicense or distribute the Program is
-void, and will automatically terminate your rights under this License.
-However, parties who have received copies, or rights, from you under
-this License will not have their licenses terminated so long as such
-parties remain in full compliance.
-
- 5. You are not required to accept this License, since you have not
-signed it. However, nothing else grants you permission to modify or
-distribute the Program or its derivative works. These actions are
-prohibited by law if you do not accept this License. Therefore, by
-modifying or distributing the Program (or any work based on the
-Program), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Program or works based on it.
-
- 6. Each time you redistribute the Program (or any work based on the
-Program), the recipient automatically receives a license from the
-original licensor to copy, distribute or modify the Program subject to
-these terms and conditions. You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties to
-this License.
-
- 7. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Program at all. For example, if a patent
-license would not permit royalty-free redistribution of the Program by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Program.
-
-If any portion of this section is held invalid or unenforceable under
-any particular circumstance, the balance of the section is intended to
-apply and the section as a whole is intended to apply in other
-circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system, which is
-implemented by public license practices. Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-\f
- 8. If the distribution and/or use of the Program is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Program under this License
-may add an explicit geographical distribution limitation excluding
-those countries, so that distribution is permitted only in or among
-countries not thus excluded. In such case, this License incorporates
-the limitation as if written in the body of this License.
-
- 9. The Free Software Foundation may publish revised and/or new versions
-of the General Public License from time to time. Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-Each version is given a distinguishing version number. If the Program
-specifies a version number of this License which applies to it and "any
-later version", you have the option of following the terms and conditions
-either of that version or of any later version published by the Free
-Software Foundation. If the Program does not specify a version number of
-this License, you may choose any version ever published by the Free Software
-Foundation.
-
- 10. If you wish to incorporate parts of the Program into other free
-programs whose distribution conditions are different, write to the author
-to ask for permission. For software which is copyrighted by the Free
-Software Foundation, write to the Free Software Foundation; we sometimes
-make exceptions for this. Our decision will be guided by the two goals
-of preserving the free status of all derivatives of our free software and
-of promoting the sharing and reuse of software generally.
-
- NO WARRANTY
-
- 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
-FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
-PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
-OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
-TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
-REPAIR OR CORRECTION.
-
- 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
-REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
-INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
-OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
-TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
-YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
-PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGES.
-
- END OF TERMS AND CONDITIONS
-\f
- How to Apply These Terms to Your New Programs
-
- If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
- To do so, attach the following notices to the program. It is safest
-to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
- <one line to give the program's name and a brief idea of what it does.>
- Copyright (C) 19yy <name of author>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-Also add information on how to contact you by electronic and paper mail.
-
-If the program is interactive, make it output a short notice like this
-when it starts in an interactive mode:
-
- Gnomovision version 69, Copyright (C) 19yy name of author
- Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
- This is free software, and you are welcome to redistribute it
- under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License. Of course, the commands you use may
-be called something other than `show w' and `show c'; they could even be
-mouse-clicks or menu items--whatever suits your program.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the program, if
-necessary. Here is a sample; alter the names:
-
- Yoyodyne, Inc., hereby disclaims all copyright interest in the program
- `Gnomovision' (which makes passes at compilers) written by James Hacker.
-
- <signature of Ty Coon>, 1 April 1989
- Ty Coon, President of Vice
-
-This General Public License does not permit incorporating your program into
-proprietary programs. If your program is a subroutine library, you may
-consider it more useful to permit linking proprietary applications with the
-library. If this is what you want to do, use the GNU Library General
-Public License instead of this License.
+++ /dev/null
- GNU LESSER GENERAL PUBLIC LICENSE
- Version 2.1, February 1999
-
- Copyright (C) 1991, 1999 Free Software Foundation, Inc.
- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-[This is the first released version of the Lesser GPL. It also counts
- as the successor of the GNU Library Public License, version 2, hence
- the version number 2.1.]
-
- Preamble
-
- The licenses for most software are designed to take away your
-freedom to share and change it. By contrast, the GNU General Public
-Licenses are intended to guarantee your freedom to share and change
-free software--to make sure the software is free for all its users.
-
- This license, the Lesser General Public License, applies to some
-specially designated software packages--typically libraries--of the
-Free Software Foundation and other authors who decide to use it. You
-can use it too, but we suggest you first think carefully about whether
-this license or the ordinary General Public License is the better
-strategy to use in any particular case, based on the explanations below.
-
- When we speak of free software, we are referring to freedom of use,
-not price. Our General Public Licenses are designed to make sure that
-you have the freedom to distribute copies of free software (and charge
-for this service if you wish); that you receive source code or can get
-it if you want it; that you can change the software and use pieces of
-it in new free programs; and that you are informed that you can do
-these things.
-
- To protect your rights, we need to make restrictions that forbid
-distributors to deny you these rights or to ask you to surrender these
-rights. These restrictions translate to certain responsibilities for
-you if you distribute copies of the library or if you modify it.
-
- For example, if you distribute copies of the library, whether gratis
-or for a fee, you must give the recipients all the rights that we gave
-you. You must make sure that they, too, receive or can get the source
-code. If you link other code with the library, you must provide
-complete object files to the recipients, so that they can relink them
-with the library after making changes to the library and recompiling
-it. And you must show them these terms so they know their rights.
-
- We protect your rights with a two-step method: (1) we copyright the
-library, and (2) we offer you this license, which gives you legal
-permission to copy, distribute and/or modify the library.
-
- To protect each distributor, we want to make it very clear that
-there is no warranty for the free library. Also, if the library is
-modified by someone else and passed on, the recipients should know
-that what they have is not the original version, so that the original
-author's reputation will not be affected by problems that might be
-introduced by others.
-\f
- Finally, software patents pose a constant threat to the existence of
-any free program. We wish to make sure that a company cannot
-effectively restrict the users of a free program by obtaining a
-restrictive license from a patent holder. Therefore, we insist that
-any patent license obtained for a version of the library must be
-consistent with the full freedom of use specified in this license.
-
- Most GNU software, including some libraries, is covered by the
-ordinary GNU General Public License. This license, the GNU Lesser
-General Public License, applies to certain designated libraries, and
-is quite different from the ordinary General Public License. We use
-this license for certain libraries in order to permit linking those
-libraries into non-free programs.
-
- When a program is linked with a library, whether statically or using
-a shared library, the combination of the two is legally speaking a
-combined work, a derivative of the original library. The ordinary
-General Public License therefore permits such linking only if the
-entire combination fits its criteria of freedom. The Lesser General
-Public License permits more lax criteria for linking other code with
-the library.
-
- We call this license the "Lesser" General Public License because it
-does Less to protect the user's freedom than the ordinary General
-Public License. It also provides other free software developers Less
-of an advantage over competing non-free programs. These disadvantages
-are the reason we use the ordinary General Public License for many
-libraries. However, the Lesser license provides advantages in certain
-special circumstances.
-
- For example, on rare occasions, there may be a special need to
-encourage the widest possible use of a certain library, so that it becomes
-a de-facto standard. To achieve this, non-free programs must be
-allowed to use the library. A more frequent case is that a free
-library does the same job as widely used non-free libraries. In this
-case, there is little to gain by limiting the free library to free
-software only, so we use the Lesser General Public License.
-
- In other cases, permission to use a particular library in non-free
-programs enables a greater number of people to use a large body of
-free software. For example, permission to use the GNU C Library in
-non-free programs enables many more people to use the whole GNU
-operating system, as well as its variant, the GNU/Linux operating
-system.
-
- Although the Lesser General Public License is Less protective of the
-users' freedom, it does ensure that the user of a program that is
-linked with the Library has the freedom and the wherewithal to run
-that program using a modified version of the Library.
-
- The precise terms and conditions for copying, distribution and
-modification follow. Pay close attention to the difference between a
-"work based on the library" and a "work that uses the library". The
-former contains code derived from the library, whereas the latter must
-be combined with the library in order to run.
-\f
- GNU LESSER GENERAL PUBLIC LICENSE
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
- 0. This License Agreement applies to any software library or other
-program which contains a notice placed by the copyright holder or
-other authorized party saying it may be distributed under the terms of
-this Lesser General Public License (also called "this License").
-Each licensee is addressed as "you".
-
- A "library" means a collection of software functions and/or data
-prepared so as to be conveniently linked with application programs
-(which use some of those functions and data) to form executables.
-
- The "Library", below, refers to any such software library or work
-which has been distributed under these terms. A "work based on the
-Library" means either the Library or any derivative work under
-copyright law: that is to say, a work containing the Library or a
-portion of it, either verbatim or with modifications and/or translated
-straightforwardly into another language. (Hereinafter, translation is
-included without limitation in the term "modification".)
-
- "Source code" for a work means the preferred form of the work for
-making modifications to it. For a library, complete source code means
-all the source code for all modules it contains, plus any associated
-interface definition files, plus the scripts used to control compilation
-and installation of the library.
-
- Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope. The act of
-running a program using the Library is not restricted, and output from
-such a program is covered only if its contents constitute a work based
-on the Library (independent of the use of the Library in a tool for
-writing it). Whether that is true depends on what the Library does
-and what the program that uses the Library does.
-
- 1. You may copy and distribute verbatim copies of the Library's
-complete source code as you receive it, in any medium, provided that
-you conspicuously and appropriately publish on each copy an
-appropriate copyright notice and disclaimer of warranty; keep intact
-all the notices that refer to this License and to the absence of any
-warranty; and distribute a copy of this License along with the
-Library.
-
- You may charge a fee for the physical act of transferring a copy,
-and you may at your option offer warranty protection in exchange for a
-fee.
-\f
- 2. You may modify your copy or copies of the Library or any portion
-of it, thus forming a work based on the Library, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
- a) The modified work must itself be a software library.
-
- b) You must cause the files modified to carry prominent notices
- stating that you changed the files and the date of any change.
-
- c) You must cause the whole of the work to be licensed at no
- charge to all third parties under the terms of this License.
-
- d) If a facility in the modified Library refers to a function or a
- table of data to be supplied by an application program that uses
- the facility, other than as an argument passed when the facility
- is invoked, then you must make a good faith effort to ensure that,
- in the event an application does not supply such function or
- table, the facility still operates, and performs whatever part of
- its purpose remains meaningful.
-
- (For example, a function in a library to compute square roots has
- a purpose that is entirely well-defined independent of the
- application. Therefore, Subsection 2d requires that any
- application-supplied function or table used by this function must
- be optional: if the application does not supply it, the square
- root function must still compute square roots.)
-
-These requirements apply to the modified work as a whole. If
-identifiable sections of that work are not derived from the Library,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works. But when you
-distribute the same sections as part of a whole which is a work based
-on the Library, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote
-it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Library.
-
-In addition, mere aggregation of another work not based on the Library
-with the Library (or with a work based on the Library) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
- 3. You may opt to apply the terms of the ordinary GNU General Public
-License instead of this License to a given copy of the Library. To do
-this, you must alter all the notices that refer to this License, so
-that they refer to the ordinary GNU General Public License, version 2,
-instead of to this License. (If a newer version than version 2 of the
-ordinary GNU General Public License has appeared, then you can specify
-that version instead if you wish.) Do not make any other change in
-these notices.
-\f
- Once this change is made in a given copy, it is irreversible for
-that copy, so the ordinary GNU General Public License applies to all
-subsequent copies and derivative works made from that copy.
-
- This option is useful when you wish to copy part of the code of
-the Library into a program that is not a library.
-
- 4. You may copy and distribute the Library (or a portion or
-derivative of it, under Section 2) in object code or executable form
-under the terms of Sections 1 and 2 above provided that you accompany
-it with the complete corresponding machine-readable source code, which
-must be distributed under the terms of Sections 1 and 2 above on a
-medium customarily used for software interchange.
-
- If distribution of object code is made by offering access to copy
-from a designated place, then offering equivalent access to copy the
-source code from the same place satisfies the requirement to
-distribute the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
- 5. A program that contains no derivative of any portion of the
-Library, but is designed to work with the Library by being compiled or
-linked with it, is called a "work that uses the Library". Such a
-work, in isolation, is not a derivative work of the Library, and
-therefore falls outside the scope of this License.
-
- However, linking a "work that uses the Library" with the Library
-creates an executable that is a derivative of the Library (because it
-contains portions of the Library), rather than a "work that uses the
-library". The executable is therefore covered by this License.
-Section 6 states terms for distribution of such executables.
-
- When a "work that uses the Library" uses material from a header file
-that is part of the Library, the object code for the work may be a
-derivative work of the Library even though the source code is not.
-Whether this is true is especially significant if the work can be
-linked without the Library, or if the work is itself a library. The
-threshold for this to be true is not precisely defined by law.
-
- If such an object file uses only numerical parameters, data
-structure layouts and accessors, and small macros and small inline
-functions (ten lines or less in length), then the use of the object
-file is unrestricted, regardless of whether it is legally a derivative
-work. (Executables containing this object code plus portions of the
-Library will still fall under Section 6.)
-
- Otherwise, if the work is a derivative of the Library, you may
-distribute the object code for the work under the terms of Section 6.
-Any executables containing that work also fall under Section 6,
-whether or not they are linked directly with the Library itself.
-\f
- 6. As an exception to the Sections above, you may also combine or
-link a "work that uses the Library" with the Library to produce a
-work containing portions of the Library, and distribute that work
-under terms of your choice, provided that the terms permit
-modification of the work for the customer's own use and reverse
-engineering for debugging such modifications.
-
- You must give prominent notice with each copy of the work that the
-Library is used in it and that the Library and its use are covered by
-this License. You must supply a copy of this License. If the work
-during execution displays copyright notices, you must include the
-copyright notice for the Library among them, as well as a reference
-directing the user to the copy of this License. Also, you must do one
-of these things:
-
- a) Accompany the work with the complete corresponding
- machine-readable source code for the Library including whatever
- changes were used in the work (which must be distributed under
- Sections 1 and 2 above); and, if the work is an executable linked
- with the Library, with the complete machine-readable "work that
- uses the Library", as object code and/or source code, so that the
- user can modify the Library and then relink to produce a modified
- executable containing the modified Library. (It is understood
- that the user who changes the contents of definitions files in the
- Library will not necessarily be able to recompile the application
- to use the modified definitions.)
-
- b) Use a suitable shared library mechanism for linking with the
- Library. A suitable mechanism is one that (1) uses at run time a
- copy of the library already present on the user's computer system,
- rather than copying library functions into the executable, and (2)
- will operate properly with a modified version of the library, if
- the user installs one, as long as the modified version is
- interface-compatible with the version that the work was made with.
-
- c) Accompany the work with a written offer, valid for at
- least three years, to give the same user the materials
- specified in Subsection 6a, above, for a charge no more
- than the cost of performing this distribution.
-
- d) If distribution of the work is made by offering access to copy
- from a designated place, offer equivalent access to copy the above
- specified materials from the same place.
-
- e) Verify that the user has already received a copy of these
- materials or that you have already sent this user a copy.
-
- For an executable, the required form of the "work that uses the
-Library" must include any data and utility programs needed for
-reproducing the executable from it. However, as a special exception,
-the materials to be distributed need not include anything that is
-normally distributed (in either source or binary form) with the major
-components (compiler, kernel, and so on) of the operating system on
-which the executable runs, unless that component itself accompanies
-the executable.
-
- It may happen that this requirement contradicts the license
-restrictions of other proprietary libraries that do not normally
-accompany the operating system. Such a contradiction means you cannot
-use both them and the Library together in an executable that you
-distribute.
-\f
- 7. You may place library facilities that are a work based on the
-Library side-by-side in a single library together with other library
-facilities not covered by this License, and distribute such a combined
-library, provided that the separate distribution of the work based on
-the Library and of the other library facilities is otherwise
-permitted, and provided that you do these two things:
-
- a) Accompany the combined library with a copy of the same work
- based on the Library, uncombined with any other library
- facilities. This must be distributed under the terms of the
- Sections above.
-
- b) Give prominent notice with the combined library of the fact
- that part of it is a work based on the Library, and explaining
- where to find the accompanying uncombined form of the same work.
-
- 8. You may not copy, modify, sublicense, link with, or distribute
-the Library except as expressly provided under this License. Any
-attempt otherwise to copy, modify, sublicense, link with, or
-distribute the Library is void, and will automatically terminate your
-rights under this License. However, parties who have received copies,
-or rights, from you under this License will not have their licenses
-terminated so long as such parties remain in full compliance.
-
- 9. You are not required to accept this License, since you have not
-signed it. However, nothing else grants you permission to modify or
-distribute the Library or its derivative works. These actions are
-prohibited by law if you do not accept this License. Therefore, by
-modifying or distributing the Library (or any work based on the
-Library), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Library or works based on it.
-
- 10. Each time you redistribute the Library (or any work based on the
-Library), the recipient automatically receives a license from the
-original licensor to copy, distribute, link with or modify the Library
-subject to these terms and conditions. You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties with
-this License.
-\f
- 11. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Library at all. For example, if a patent
-license would not permit royalty-free redistribution of the Library by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Library.
-
-If any portion of this section is held invalid or unenforceable under any
-particular circumstance, the balance of the section is intended to apply,
-and the section as a whole is intended to apply in other circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system which is
-implemented by public license practices. Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
- 12. If the distribution and/or use of the Library is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Library under this License may add
-an explicit geographical distribution limitation excluding those countries,
-so that distribution is permitted only in or among countries not thus
-excluded. In such case, this License incorporates the limitation as if
-written in the body of this License.
-
- 13. The Free Software Foundation may publish revised and/or new
-versions of the Lesser General Public License from time to time.
-Such new versions will be similar in spirit to the present version,
-but may differ in detail to address new problems or concerns.
-
-Each version is given a distinguishing version number. If the Library
-specifies a version number of this License which applies to it and
-"any later version", you have the option of following the terms and
-conditions either of that version or of any later version published by
-the Free Software Foundation. If the Library does not specify a
-license version number, you may choose any version ever published by
-the Free Software Foundation.
-\f
- 14. If you wish to incorporate parts of the Library into other free
-programs whose distribution conditions are incompatible with these,
-write to the author to ask for permission. For software which is
-copyrighted by the Free Software Foundation, write to the Free
-Software Foundation; we sometimes make exceptions for this. Our
-decision will be guided by the two goals of preserving the free status
-of all derivatives of our free software and of promoting the sharing
-and reuse of software generally.
-
- NO WARRANTY
-
- 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
-WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
-EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
-OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
-KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
-LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
-THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-
- 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
-WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
-AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
-FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
-CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
-LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
-RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
-FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
-SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
-DAMAGES.
-
- END OF TERMS AND CONDITIONS
-\f
- How to Apply These Terms to Your New Libraries
-
- If you develop a new library, and you want it to be of the greatest
-possible use to the public, we recommend making it free software that
-everyone can redistribute and change. You can do so by permitting
-redistribution under these terms (or, alternatively, under the terms of the
-ordinary General Public License).
-
- To apply these terms, attach the following notices to the library. It is
-safest to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least the
-"copyright" line and a pointer to where the full notice is found.
-
- <one line to give the library's name and a brief idea of what it does.>
- Copyright (C) <year> <name of author>
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-Also add information on how to contact you by electronic and paper mail.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the library, if
-necessary. Here is a sample; alter the names:
-
- Yoyodyne, Inc., hereby disclaims all copyright interest in the
- library `Frob' (a library for tweaking knobs) written by James Random Hacker.
-
- <signature of Ty Coon>, 1 April 1990
- Ty Coon, President of Vice
-
-That's all there is to it!
-
-
+++ /dev/null
-version 0.6.1:
-
- - Mac OS X port (Pierre d'Herbemont)
- - Virtual console support
- - Better monitor line edition
- - New block device layer
- - New 'qcow' growable disk image support with AES encryption and
- transparent decompression
- - VMware 3 and 4 read-only disk image support (untested)
- - Support for up to 4 serial ports
- - TFTP server support (Magnus Damm)
- - Port redirection support in user mode networking
- - Support for not executable data sections
- - Compressed loop disk image support (Johannes Schindelin)
- - Level triggered IRQ fix (aka NE2000 PCI performance fix) (Steve
- Wormley)
- - Fixed Fedora Core 2 problems (now you can run qemu without any
- LD_ASSUME_KERNEL tricks on FC2)
- - DHCP fix for Windows (accept DHCPREQUEST alone)
- - SPARC system emulation (Blue Swirl)
- - Automatic Samba configuration for host file access from Windows.
- - '-loadvm' and '-full-screen' options
- - ne2000 savevm support (Johannes Schindelin)
- - Ctrl-Alt is now the default grab key. Ctrl-Alt-[0-9] switches to
- the virtual consoles.
- - BIOS floppy fix for NT4 (Mike Nordell, Derek Fawcus, Volker Ruppert)
- - Floppy fixes for NT4 and NT5 (Mike Nordell)
- - NT4 IDE fixes (Ben Pfaf, Mike Nordell)
- - SDL Audio support and SB16 fixes (malc)
- - ENTER instruction bug fix (initial patch by Stefan Kisdaroczi)
- - VGA font change fix
- - VGA read-only CRTC register fix
-
-version 0.6.0:
-
- - minimalist FPU exception support (NetBSD FPU probe fix)
- - cr0.ET fix (Win95 boot)
- - *BSD port (Markus Niemisto)
- - I/O access fix (signaled by Mark Jonckheere)
- - IDE drives serial number fix (Mike Nordell)
- - int13 CDROM BIOS fix (aka Solaris x86 install CD fix)
- - int15, ah=86 BIOS fix (aka Solaris x86 hardware probe hang up fix)
- - BSR/BSF "undefined behaviour" fix
- - vmdk2raw: convert VMware disk images to raw images
- - PCI support
- - NE2K PCI support
- - dummy VGA PCI support
- - VGA font selection fix (Daniel Serpell)
- - PIC reset fix (Hidemi KAWAI)
- - PIC spurious irq support (aka Solaris install bug)
- - added '-localtime' option
- - Cirrus CL-GD54xx VGA support (initial patch by Makoto Suzuki (suzu))
- - APM and system shutdown support
- - Fixed system reset
- - Support for other PC BIOSes
- - Initial PowerMac hardware emulation
- - PowerMac/PREP OpenFirmware compatible BIOS (Jocelyn Mayer)
- - initial IDE BMDMA support (needed for Darwin x86)
- - Set the default memory size for PC emulation to 128 MB
-
-version 0.5.5:
-
- - SDL full screen support (initial patch by malc)
- - VGA support on PowerPC PREP
- - VBE fixes (Matthew Mastracci)
- - PIT fixes (aka Win98 hardware probe and "VGA slowness" bug)
- - IDE master only fixes (aka Win98 CD-ROM probe bug)
- - ARM load/store half word fix (Ulrich Hecht)
- - FDC fixes for Win98
-
-version 0.5.4:
-
- - qemu-fast fixes
- - BIOS area protection fix (aka EMM386.EXE fix) (Mike Nordell)
- - keyboard/mouse fix (Mike Nordell)
- - IDE fixes (Linux did not recognized slave drivers)
- - VM86 EIP masking fix (aka NT5 install fix) (Mike Nordell)
- - QEMU can now boot a PowerPC Linux kernel (Jocelyn Mayer)
- - User mode network stack
- - imul imm8 fix + 0x82 opcode support (Hidemi KAWAI)
- - precise self modifying code (aka BeOS install bug)
-
-version 0.5.3:
-
- - added Bochs VESA VBE support
- - VGA memory map mode 3 access fix (OS/2 install fix)
- - IDE fixes (Jens Axboe)
- - CPU interrupt fixes
- - fixed various TLB invalidation cases (NT install)
- - fixed cr0.WP semantics (XP install)
- - direct chaining support for SPARC and PowerPC (faster)
- - ARM NWFPE support (initial patch by Ulrich Hecht)
- - added specific x86 to x86 translator (close to native performance
- in qemu-i386 and qemu-fast)
- - shm syscalls support (Paul McKerras)
- - added accurate CR0.MP/ME/TS emulation
- - fixed DMA memory write access (Win95 boot floppy fix)
- - graphical x86 linux loader
- - command line monitor
- - generic removable device support
- - support of CD-ROM change
- - multiple network interface support
- - initial x86-64 host support (Gwenole Beauchesne)
- - lret to outer priviledge fix (OS/2 install fix)
- - task switch fixes (SkyOS boot)
- - VM save/restore commands
- - new timer API
- - more precise RTC emulation (periodic timers + time updates)
- - Win32 port (initial patch by Kazu)
-
-version 0.5.2:
-
- - improved soft MMU speed (assembly functions and specializing)
- - improved multitasking speed by avoiding flushing TBs when
- switching tasks
- - improved qemu-fast speed
- - improved self modifying code handling (big performance gain in
- softmmu mode).
- - fixed IO checking
- - fixed CD-ROM detection (win98 install CD)
- - fixed addseg real mode bug (GRUB boot fix)
- - added ROM memory support (win98 boot)
- - fixed 'call Ev' in case of paging exception
- - updated the script 'qemu-binfmt-conf.sh' to use QEMU automagically
- when launching executables for the supported target CPUs.
- - PowerPC system emulation update (Jocelyn Mayer)
- - PC floppy emulation and DMA fixes (Jocelyn Mayer)
- - polled mode for PIC (Jocelyn Mayer)
- - fixed PTE dirty bit handling
- - fixed xadd same reg bug
- - fixed cmpxchg exception safeness
- - access to virtual memory in gdb stub
- - task gate and NT flag fixes
- - eflags optimisation fix for string operations
-
-version 0.5.1:
-
- - float access fixes when using soft mmu
- - PC emulation support on PowerPC
- - A20 support
- - IDE CD-ROM emulation
- - ARM fixes (Ulrich Hecht)
- - SB16 emulation (malc)
- - IRET and INT fixes in VM86 mode with IOPL=3
- - Port I/Os use TSS io map
- - Full task switching/task gate support
- - added verr, verw, arpl, fcmovxx
- - PowerPC target support (Jocelyn Mayer)
- - Major SPARC target fixes (dynamically linked programs begin to work)
-
-version 0.5.0:
-
- - full hardware level VGA emulation
- - graphical display with SDL
- - added PS/2 mouse and keyboard emulation
- - popw (%esp) fix
- - mov to/from segment data width fix
- - added real mode support
- - added Bochs BIOS and LGPL'ed VGA BIOS loader in qemu
- - m68k host port (Richard Zidlicky)
- - partial soft MMU support for memory mapped I/Os
- - multi-target build
- - fixed: no error code in hardware interrupts
- - fixed: pop ss, mov ss, x and sti disable hardware irqs for the next insn
- - correct single stepping thru string operations
- - preliminary SPARC target support (Thomas M. Ogrisegg)
- - tun-fd option (Rusty Russell)
- - automatic IDE geometry detection
- - renamed 'vl' to qemu[-fast] and user qemu to qemu-{cpu}.
- - added man page
- - added full soft mmu mode to launch unpatched OSes.
-
-version 0.4.3:
-
- - x86 exception fix in case of nop instruction.
- - gcc 3.2.2 bug workaround (RedHat 9 fix)
- - sparc and Alpha host fixes
- - many ARM target fixes: 'ls' and 'bash' can be launched.
-
-version 0.4.2:
-
- - many exception handling fixes (can compile a Linux kernel inside vl)
- - IDE emulation support
- - initial GDB stub support
- - deferred update support for disk images (Rusty Russell)
- - accept User Mode Linux Copy On Write disk images
- - SMP kernels can at least be booted
-
-version 0.4.1:
-
- - more accurate timer support in vl.
- - more reliable NE2000 probe in vl.
- - added 2.5.66 kernel in vl-test.
- - added VLTMPDIR environment variable in vl.
-
-version 0.4:
-
- - initial support for ring 0 x86 processor emulation
- - fixed signal handling for correct dosemu DPMI emulation
- - fast x86 MMU emulation with mmap()
- - fixed popl (%esp) case
- - Linux kernel can be executed by QEMU with the 'vl' command.
-
-version 0.3:
-
- - initial support for ARM emulation
- - added fnsave, frstor, fnstenv, fldenv FPU instructions
- - added FPU register save in signal emulation
- - initial ARM port
- - Sparc and Alpha ports work on the regression test
- - generic ioctl number conversion
- - fixed ioctl type conversion
-
-version 0.2:
-
- - PowerPC disassembly and ELF symbols output (Rusty Russell)
- - flock support (Rusty Russell)
- - ugetrlimit support (Rusty Russell)
- - fstat64 fix (Rusty Russell)
- - initial Alpha port (Falk Hueffner)
- - initial IA64 port (Matt Wilson)
- - initial Sparc and Sparc64 port (David S. Miller)
- - added HLT instruction
- - LRET instruction fix.
- - added GPF generation for I/Os.
- - added INT3 and TF flag support.
- - SHL instruction C flag fix.
- - mmap emulation for host page size > 4KB
- - self-modifying code support
- - better VM86 support (dosemu works on non trivial programs)
- - precise exception support (EIP is computed correctly in most cases)
- - more precise LDT/GDT/IDT emulation
- - faster segment load in vm86 mode
- - direct chaining of basic blocks (faster emulation)
-
-version 0.1.6:
-
- - automatic library search system. QEMU can now work with unpatched
- ELF dynamic loader and libc (Rusty Russell).
- - ISO C warning fixes (Alistair Strachan)
- - first self-virtualizable version (works only as long as the
- translation cache is not flushed)
- - RH9 fixes
-
-version 0.1.5:
-
- - ppc64 support + personality() patch (Rusty Russell)
- - first Alpha CPU patches (Falk Hueffner)
- - removed bfd.h dependancy
- - fixed shrd, shld, idivl and divl on PowerPC.
- - fixed buggy glibc PowerPC rint() function (test-i386 passes now on PowerPC).
-
-version 0.1.4:
-
- - more accurate VM86 emulation (can launch small DOS 16 bit
- executables in wine).
- - fixed push/pop fs/gs
- - added iret instruction.
- - added times() syscall and SIOCATMARK ioctl.
-
-version 0.1.3:
-
- - S390 support (Ulrich Weigand)
- - glibc 2.3.x compile fix (Ulrich Weigand)
- - socketcall endian fix (Ulrich Weigand)
- - struct sockaddr endian fix (Ulrich Weigand)
- - sendmsg/recvmsg endian fix (Ulrich Weigand)
- - execve endian fix (Ulrich Weigand)
- - fdset endian fix (Ulrich Weigand)
- - partial setsockopt syscall support (Ulrich Weigand)
- - more accurate pushf/popf emulation
- - first partial vm86() syscall support (can be used with runcom example).
- - added bound, cmpxchg8b, cpuid instructions
- - added 16 bit addressing support/override for string operations
- - poll() fix
-
-version 0.1.2:
-
- - compile fixes
- - xlat instruction
- - xchg instruction memory lock
- - added simple vm86 example (not working with QEMU yet). The 54 byte
- DOS executable 'pi_10.com' program was released by Bertram
- Felgenhauer (more information at http://www.boo.net/~jasonp/pipage.html).
-
-version 0.1.1:
-
- - glibc 2.2 compilation fixes
- - added -s and -L options
- - binary distribution of x86 glibc and wine
- - big endian fixes in ELF loader and getdents.
-
-version 0.1:
-
- - initial public release.
+++ /dev/null
-XEN_ROOT=../..
-include $(XEN_ROOT)/tools/Rules.mk
-
--include config-host.mak
-
-CFLAGS+=-g -fno-strict-aliasing
-ifdef CONFIG_DARWIN
-CFLAGS+= -mdynamic-no-pic
-endif
-ifdef CONFIG_WIN32
-CFLAGS+=-fpack-struct
-endif
-LDFLAGS=-g
-LIBS=
-DEFINES+=-D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE
-TOOLS=qemu-img
-ifdef CONFIG_STATIC
-LDFLAGS+=-static
-endif
-#DOCS=qemu-doc.html qemu-tech.html qemu.1
-
-.PHONY: all
-all: $(DOCS) HEADERS
- for d in $(TARGET_DIRS); do \
- $(MAKE) -C $$d $@ || exit 1 ; \
- done
-
-qemu-img: qemu-img.c block.c block-cow.c block-qcow.c aes.c block-vmdk.c block-cloop.c
- $(CC) -DQEMU_TOOL $(CFLAGS) $(LDFLAGS) $(DEFINES) -o $@ $^ -lz $(LIBS)
-
-dyngen$(EXESUF): dyngen.c
- $(HOST_CC) $(CFLAGS) $(DEFINES) -o $@ $^
-
-.PHONY: clean
-clean:
-# avoid old build problems by removing potentially incorrect old files
- rm -f config.mak config.h op-i386.h opc-i386.h gen-op-i386.h op-arm.h opc-arm.h gen-op-arm.h
- rm -f *.o *.a $(TOOLS) dyngen$(EXESUF) TAGS qemu.pod *~ */*~
- #$(MAKE) -C tests clean
- for d in $(TARGET_DIRS); do \
- $(MAKE) -C $$d $@ || exit 1 ; \
- done
- rm -f config-host.mak config-host.h
- rm -f keysym_adapter_sdl.h keysym_adapter_vnc.h
-
-.PHONY: distclean
-distclean: clean
- rm -f config-host.mak config-host.h
- rm -f keysym_adapter_sdl.h keysym_adapter_vnc.h
- for d in $(TARGET_DIRS); do \
- $(MAKE) -C $$d $@ || exit 1 ; \
- done
-
-KEYMAPS=da en-gb et fr fr-ch is lt modifiers no pt-br sv \
-ar de en-us fi fr-be hr it lv nl pl ru th \
-common de-ch es fo fr-ca hu ja mk nl-be pt sl tr
-
-.PHONY: install
-install: all
- mkdir -p "$(bindir)"
- mkdir -p "$(DESTDIR)/$(datadir)"
- mkdir -p "$(DESTDIR)/$(datadir)/keymaps"
- install -m 644 $(addprefix keymaps/,$(KEYMAPS)) "$(DESTDIR)/$(datadir)/keymaps"
- for d in $(TARGET_DIRS); do \
- $(MAKE) -C $$d $@ || exit 1 ; \
- done
-
-# various test targets
-.PHONY: test speed test2
-test speed test2: all
- $(MAKE) -C tests $@
-
-.PHONY: TAGS
-TAGS:
- etags *.[ch] tests/*.[ch]
-
-# documentation
-%.html: %.texi
- texi2html -monolithic -number $<
-
-qemu.1: qemu-doc.texi
- ./texi2pod.pl $< qemu.pod
- pod2man --section=1 --center=" " --release=" " qemu.pod > $@
-
-FILE=qemu-$(shell cat VERSION)
-
-# tar release (use 'make -k tar' on a checkouted tree)
-.PHONY: tar
-tar:
- rm -rf /tmp/$(FILE)
- cp -r . /tmp/$(FILE)
- ( cd /tmp ; tar zcvf ~/$(FILE).tar.gz $(FILE) --exclude CVS )
- rm -rf /tmp/$(FILE)
-
-# generate a binary distribution
-.PHONY: tarbin
-tarbin:
- ( cd $(DESTDIR) ; tar zcvf ~/qemu-$(VERSION)-i386.tar.gz \
- $(DESTDIR)/$(bindir)/qemu $(DESTDIR)/$(bindir)/qemu-fast \
- $(DESTDIR)/$(bindir)/qemu-system-ppc \
- $(DESTDIR)/$(bindir)/qemu-i386 \
- $(DESTDIR)/$(bindir)/qemu-arm \
- $(DESTDIR)/$(bindir)/qemu-sparc \
- $(DESTDIR)/$(bindir)/qemu-ppc \
- $(DESTDIR)/$(mandir)/man1/qemu.1 $(DESTDIR)/$(mandir)/man1/qemu-mkcow.1 )
-
-ifneq ($(wildcard .depend),)
-include .depend
-endif
-
-.PHONY: HEADERS
-HEADERS:
-
-ifdef CONFIG_SDL
-HEADERS: keysym_adapter_sdl.h
-endif
-
-ifdef CONFIG_VNC
-HEADERS: keysym_adapter_vnc.h
-endif
-
-keysym_adapter_sdl.h: Makefile create_keysym_header.sh
- sh create_keysym_header.sh sdl "$(SDL_CFLAGS)"
-
-keysym_adapter_vnc.h: Makefile create_keysym_header.sh
- sh create_keysym_header.sh vnc "$(VNC_CFLAGS)"
-
-
+++ /dev/null
-The QEMU x86 emulator
----------------------
-
-INSTALLATION
-------------
-
-Type
-
- ./configure
- make
-
-to build qemu, qemu-CPU and libqemu.a (CPU is the name of the various
-supported target CPUs).
-
-Type
-
- make install
-
-to install QEMU in /usr/local
-
-Tested tool versions
---------------------
-
-In order to compile QEMU succesfully, it is very important that you
-have the right tools. The most important one is gcc. I cannot guaranty
-that QEMU works if you do not use a tested gcc version. Look at
-'configure' and 'Makefile' if you want to make a different gcc
-version work.
-
-host gcc binutils glibc linux distribution
-----------------------------------------------------------------------
-x86 2.95.2 2.13.2 2.1.3 2.4.18
- 3.2 2.13.2 2.1.3 2.4.18
- 2.96 2.11.93.0.2 2.2.5 2.4.18 Red Hat 7.3
- 3.2.2 2.13.90.0.18 2.3.2 2.4.20 Red Hat 9
-
-PowerPC 3.3 [4] 2.13.90.0.18 2.3.1 2.4.20briq
- 3.2
-
-Alpha 3.3 [1] 2.14.90.0.4 2.2.5 2.2.20 [2] Debian 3.0
-
-Sparc32 2.95.4 2.12.90.0.1 2.2.5 2.4.18 Debian 3.0
-
-ARM 2.95.4 2.12.90.0.1 2.2.5 2.4.9 [3] Debian 3.0
-
-[1] On Alpha, QEMU needs the gcc 'visibility' attribute only available
- for gcc version >= 3.3.
-[2] Linux >= 2.4.20 is necessary for precise exception support
- (untested).
-[3] 2.4.9-ac10-rmk2-np1-cerf2
-
-[4] gcc 2.95.x generates invalid code when using too many register
-variables. You must use gcc 3.x on PowerPC.
-
-Documentation
--------------
-
-Read the documentation in qemu-doc.html.
-
-
-Fabrice Bellard.
\ No newline at end of file
+++ /dev/null
-short term:
-----------
-- debug option in 'configure' script + disable -fomit-frame-pointer
-- Solaris display error with Cirrus VGA
- (http://lists.gnu.org/archive/html/qemu-devel/2004-10/msg00390.html).
-- Precise VGA timings for old games/demos (malc patch)
-- merge PIC spurious interrupt patch
-- merge VNC keyboard patch
-- merge Solaris patch
-- merge ARM patches + self modifying code patch (Paul Brook)
-- warning for OS/2: must not use 128 MB memory
-- config file (at least for windows/Mac OS X)
-- commit message if execution of code in IO memory
-- update doc: PCI infos.
-- VNC patch + Synaptic patch.
-- basic VGA optimizations
-- test sysenter/sysexit and fxsr for L4 pistachio 686
-- physical memory cache (reduce qemu-fast address space size to about 32 MB)
-- better code fetch (different exception handling + CS.limit support)
-- do not resize vga if invalid size.
-- avoid looping if only exceptions
-- cycle counter for all archs
-- TLB code protection support for PPC
-- see openMosix Doc
-- disable SMC handling for ARM/SPARC/PPC (not finished)
-- see undefined flags for BTx insn
-- user/kernel PUSHL/POPL in helper.c
-- keyboard output buffer filling timing emulation
-- return UD exception if LOCK prefix incorrectly used
-- test ldt limit < 7 ?
-- tests for each target CPU
-- fix CCOP optimisation
-- fix all remaining thread lock issues (must put TBs in a specific invalid
- state, find a solution for tb_flush()).
-- fix arm fpu rounding (at least for float->integer conversions)
-- SMP support
-
-ppc specific:
-------------
-- TLB invalidate not needed if msr_pr changes
-- endianness bugs in do_load_fpscr and do_store_fpscr
-- SPR_ENCODE() not useful
-- enable shift optimizations ?
-
-lower priority:
---------------
-- more friendly BIOS (logo)
-- int15 ah=86: use better timing
-- HDD geometry in CMOS (not used except for very old DOS programs)
-- suppress shift_mem ops
-- fix some 16 bit sp push/pop overflow (pusha/popa, lcall lret)
-- sysenter/sysexit emulation
-- optimize FPU operations (evaluate x87 stack pointer statically)
-- add IPC syscalls
-- use -msoft-float on ARM
-- use kernel traps for unaligned accesses on ARM ?
-- handle rare page fault cases (in particular if page fault in helpers or
- in syscall emulation code).
-- fix thread stack freeing (use kernel 2.5.x CLONE_CHILD_CLEARTID)
-- more syscalls (in particular all 64 bit ones, IPCs, fix 64 bit
- issues, fix 16 bit uid issues)
-- use page_unprotect_range in every suitable syscall to handle all
- cases of self modifying code.
-- use gcc as a backend to generate better code (easy to do by using
- op-i386.c operations as local inline functions).
-- add SSE2/MMX operations
+++ /dev/null
-0.6.1
\ No newline at end of file
+++ /dev/null
-/**
- *
- * aes.c - integrated in QEMU by Fabrice Bellard from the OpenSSL project.
- */
-/*
- * rijndael-alg-fst.c
- *
- * @version 3.0 (December 2000)
- *
- * Optimised ANSI C code for the Rijndael cipher (now AES)
- *
- * @author Vincent Rijmen <vincent.rijmen@esat.kuleuven.ac.be>
- * @author Antoon Bosselaers <antoon.bosselaers@esat.kuleuven.ac.be>
- * @author Paulo Barreto <paulo.barreto@terra.com.br>
- *
- * This code is hereby placed in the public domain.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
- * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-#include "vl.h"
-#include "aes.h"
-
-#define NDEBUG
-#include <assert.h>
-
-typedef uint32_t u32;
-typedef uint16_t u16;
-typedef uint8_t u8;
-
-#define MAXKC (256/32)
-#define MAXKB (256/8)
-#define MAXNR 14
-
-/* This controls loop-unrolling in aes_core.c */
-#undef FULL_UNROLL
-# define GETU32(pt) (((u32)(pt)[0] << 24) ^ ((u32)(pt)[1] << 16) ^ ((u32)(pt)[2] << 8) ^ ((u32)(pt)[3]))
-# define PUTU32(ct, st) { (ct)[0] = (u8)((st) >> 24); (ct)[1] = (u8)((st) >> 16); (ct)[2] = (u8)((st) >> 8); (ct)[3] = (u8)(st); }
-
-/*
-Te0[x] = S [x].[02, 01, 01, 03];
-Te1[x] = S [x].[03, 02, 01, 01];
-Te2[x] = S [x].[01, 03, 02, 01];
-Te3[x] = S [x].[01, 01, 03, 02];
-Te4[x] = S [x].[01, 01, 01, 01];
-
-Td0[x] = Si[x].[0e, 09, 0d, 0b];
-Td1[x] = Si[x].[0b, 0e, 09, 0d];
-Td2[x] = Si[x].[0d, 0b, 0e, 09];
-Td3[x] = Si[x].[09, 0d, 0b, 0e];
-Td4[x] = Si[x].[01, 01, 01, 01];
-*/
-
-static const u32 Te0[256] = {
- 0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU,
- 0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U,
- 0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU,
- 0xe7fefe19U, 0xb5d7d762U, 0x4dababe6U, 0xec76769aU,
- 0x8fcaca45U, 0x1f82829dU, 0x89c9c940U, 0xfa7d7d87U,
- 0xeffafa15U, 0xb25959ebU, 0x8e4747c9U, 0xfbf0f00bU,
- 0x41adadecU, 0xb3d4d467U, 0x5fa2a2fdU, 0x45afafeaU,
- 0x239c9cbfU, 0x53a4a4f7U, 0xe4727296U, 0x9bc0c05bU,
- 0x75b7b7c2U, 0xe1fdfd1cU, 0x3d9393aeU, 0x4c26266aU,
- 0x6c36365aU, 0x7e3f3f41U, 0xf5f7f702U, 0x83cccc4fU,
- 0x6834345cU, 0x51a5a5f4U, 0xd1e5e534U, 0xf9f1f108U,
- 0xe2717193U, 0xabd8d873U, 0x62313153U, 0x2a15153fU,
- 0x0804040cU, 0x95c7c752U, 0x46232365U, 0x9dc3c35eU,
- 0x30181828U, 0x379696a1U, 0x0a05050fU, 0x2f9a9ab5U,
- 0x0e070709U, 0x24121236U, 0x1b80809bU, 0xdfe2e23dU,
- 0xcdebeb26U, 0x4e272769U, 0x7fb2b2cdU, 0xea75759fU,
- 0x1209091bU, 0x1d83839eU, 0x582c2c74U, 0x341a1a2eU,
- 0x361b1b2dU, 0xdc6e6eb2U, 0xb45a5aeeU, 0x5ba0a0fbU,
- 0xa45252f6U, 0x763b3b4dU, 0xb7d6d661U, 0x7db3b3ceU,
- 0x5229297bU, 0xdde3e33eU, 0x5e2f2f71U, 0x13848497U,
- 0xa65353f5U, 0xb9d1d168U, 0x00000000U, 0xc1eded2cU,
- 0x40202060U, 0xe3fcfc1fU, 0x79b1b1c8U, 0xb65b5bedU,
- 0xd46a6abeU, 0x8dcbcb46U, 0x67bebed9U, 0x7239394bU,
- 0x944a4adeU, 0x984c4cd4U, 0xb05858e8U, 0x85cfcf4aU,
- 0xbbd0d06bU, 0xc5efef2aU, 0x4faaaae5U, 0xedfbfb16U,
- 0x864343c5U, 0x9a4d4dd7U, 0x66333355U, 0x11858594U,
- 0x8a4545cfU, 0xe9f9f910U, 0x04020206U, 0xfe7f7f81U,
- 0xa05050f0U, 0x783c3c44U, 0x259f9fbaU, 0x4ba8a8e3U,
- 0xa25151f3U, 0x5da3a3feU, 0x804040c0U, 0x058f8f8aU,
- 0x3f9292adU, 0x219d9dbcU, 0x70383848U, 0xf1f5f504U,
- 0x63bcbcdfU, 0x77b6b6c1U, 0xafdada75U, 0x42212163U,
- 0x20101030U, 0xe5ffff1aU, 0xfdf3f30eU, 0xbfd2d26dU,
- 0x81cdcd4cU, 0x180c0c14U, 0x26131335U, 0xc3ecec2fU,
- 0xbe5f5fe1U, 0x359797a2U, 0x884444ccU, 0x2e171739U,
- 0x93c4c457U, 0x55a7a7f2U, 0xfc7e7e82U, 0x7a3d3d47U,
- 0xc86464acU, 0xba5d5de7U, 0x3219192bU, 0xe6737395U,
- 0xc06060a0U, 0x19818198U, 0x9e4f4fd1U, 0xa3dcdc7fU,
- 0x44222266U, 0x542a2a7eU, 0x3b9090abU, 0x0b888883U,
- 0x8c4646caU, 0xc7eeee29U, 0x6bb8b8d3U, 0x2814143cU,
- 0xa7dede79U, 0xbc5e5ee2U, 0x160b0b1dU, 0xaddbdb76U,
- 0xdbe0e03bU, 0x64323256U, 0x743a3a4eU, 0x140a0a1eU,
- 0x924949dbU, 0x0c06060aU, 0x4824246cU, 0xb85c5ce4U,
- 0x9fc2c25dU, 0xbdd3d36eU, 0x43acacefU, 0xc46262a6U,
- 0x399191a8U, 0x319595a4U, 0xd3e4e437U, 0xf279798bU,
- 0xd5e7e732U, 0x8bc8c843U, 0x6e373759U, 0xda6d6db7U,
- 0x018d8d8cU, 0xb1d5d564U, 0x9c4e4ed2U, 0x49a9a9e0U,
- 0xd86c6cb4U, 0xac5656faU, 0xf3f4f407U, 0xcfeaea25U,
- 0xca6565afU, 0xf47a7a8eU, 0x47aeaee9U, 0x10080818U,
- 0x6fbabad5U, 0xf0787888U, 0x4a25256fU, 0x5c2e2e72U,
- 0x381c1c24U, 0x57a6a6f1U, 0x73b4b4c7U, 0x97c6c651U,
- 0xcbe8e823U, 0xa1dddd7cU, 0xe874749cU, 0x3e1f1f21U,
- 0x964b4bddU, 0x61bdbddcU, 0x0d8b8b86U, 0x0f8a8a85U,
- 0xe0707090U, 0x7c3e3e42U, 0x71b5b5c4U, 0xcc6666aaU,
- 0x904848d8U, 0x06030305U, 0xf7f6f601U, 0x1c0e0e12U,
- 0xc26161a3U, 0x6a35355fU, 0xae5757f9U, 0x69b9b9d0U,
- 0x17868691U, 0x99c1c158U, 0x3a1d1d27U, 0x279e9eb9U,
- 0xd9e1e138U, 0xebf8f813U, 0x2b9898b3U, 0x22111133U,
- 0xd26969bbU, 0xa9d9d970U, 0x078e8e89U, 0x339494a7U,
- 0x2d9b9bb6U, 0x3c1e1e22U, 0x15878792U, 0xc9e9e920U,
- 0x87cece49U, 0xaa5555ffU, 0x50282878U, 0xa5dfdf7aU,
- 0x038c8c8fU, 0x59a1a1f8U, 0x09898980U, 0x1a0d0d17U,
- 0x65bfbfdaU, 0xd7e6e631U, 0x844242c6U, 0xd06868b8U,
- 0x824141c3U, 0x299999b0U, 0x5a2d2d77U, 0x1e0f0f11U,
- 0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U, 0x2c16163aU,
-};
-static const u32 Te1[256] = {
- 0xa5c66363U, 0x84f87c7cU, 0x99ee7777U, 0x8df67b7bU,
- 0x0dfff2f2U, 0xbdd66b6bU, 0xb1de6f6fU, 0x5491c5c5U,
- 0x50603030U, 0x03020101U, 0xa9ce6767U, 0x7d562b2bU,
- 0x19e7fefeU, 0x62b5d7d7U, 0xe64dababU, 0x9aec7676U,
- 0x458fcacaU, 0x9d1f8282U, 0x4089c9c9U, 0x87fa7d7dU,
- 0x15effafaU, 0xebb25959U, 0xc98e4747U, 0x0bfbf0f0U,
- 0xec41adadU, 0x67b3d4d4U, 0xfd5fa2a2U, 0xea45afafU,
- 0xbf239c9cU, 0xf753a4a4U, 0x96e47272U, 0x5b9bc0c0U,
- 0xc275b7b7U, 0x1ce1fdfdU, 0xae3d9393U, 0x6a4c2626U,
- 0x5a6c3636U, 0x417e3f3fU, 0x02f5f7f7U, 0x4f83ccccU,
- 0x5c683434U, 0xf451a5a5U, 0x34d1e5e5U, 0x08f9f1f1U,
- 0x93e27171U, 0x73abd8d8U, 0x53623131U, 0x3f2a1515U,
- 0x0c080404U, 0x5295c7c7U, 0x65462323U, 0x5e9dc3c3U,
- 0x28301818U, 0xa1379696U, 0x0f0a0505U, 0xb52f9a9aU,
- 0x090e0707U, 0x36241212U, 0x9b1b8080U, 0x3ddfe2e2U,
- 0x26cdebebU, 0x694e2727U, 0xcd7fb2b2U, 0x9fea7575U,
- 0x1b120909U, 0x9e1d8383U, 0x74582c2cU, 0x2e341a1aU,
- 0x2d361b1bU, 0xb2dc6e6eU, 0xeeb45a5aU, 0xfb5ba0a0U,
- 0xf6a45252U, 0x4d763b3bU, 0x61b7d6d6U, 0xce7db3b3U,
- 0x7b522929U, 0x3edde3e3U, 0x715e2f2fU, 0x97138484U,
- 0xf5a65353U, 0x68b9d1d1U, 0x00000000U, 0x2cc1ededU,
- 0x60402020U, 0x1fe3fcfcU, 0xc879b1b1U, 0xedb65b5bU,
- 0xbed46a6aU, 0x468dcbcbU, 0xd967bebeU, 0x4b723939U,
- 0xde944a4aU, 0xd4984c4cU, 0xe8b05858U, 0x4a85cfcfU,
- 0x6bbbd0d0U, 0x2ac5efefU, 0xe54faaaaU, 0x16edfbfbU,
- 0xc5864343U, 0xd79a4d4dU, 0x55663333U, 0x94118585U,
- 0xcf8a4545U, 0x10e9f9f9U, 0x06040202U, 0x81fe7f7fU,
- 0xf0a05050U, 0x44783c3cU, 0xba259f9fU, 0xe34ba8a8U,
- 0xf3a25151U, 0xfe5da3a3U, 0xc0804040U, 0x8a058f8fU,
- 0xad3f9292U, 0xbc219d9dU, 0x48703838U, 0x04f1f5f5U,
- 0xdf63bcbcU, 0xc177b6b6U, 0x75afdadaU, 0x63422121U,
- 0x30201010U, 0x1ae5ffffU, 0x0efdf3f3U, 0x6dbfd2d2U,
- 0x4c81cdcdU, 0x14180c0cU, 0x35261313U, 0x2fc3ececU,
- 0xe1be5f5fU, 0xa2359797U, 0xcc884444U, 0x392e1717U,
- 0x5793c4c4U, 0xf255a7a7U, 0x82fc7e7eU, 0x477a3d3dU,
- 0xacc86464U, 0xe7ba5d5dU, 0x2b321919U, 0x95e67373U,
- 0xa0c06060U, 0x98198181U, 0xd19e4f4fU, 0x7fa3dcdcU,
- 0x66442222U, 0x7e542a2aU, 0xab3b9090U, 0x830b8888U,
- 0xca8c4646U, 0x29c7eeeeU, 0xd36bb8b8U, 0x3c281414U,
- 0x79a7dedeU, 0xe2bc5e5eU, 0x1d160b0bU, 0x76addbdbU,
- 0x3bdbe0e0U, 0x56643232U, 0x4e743a3aU, 0x1e140a0aU,
- 0xdb924949U, 0x0a0c0606U, 0x6c482424U, 0xe4b85c5cU,
- 0x5d9fc2c2U, 0x6ebdd3d3U, 0xef43acacU, 0xa6c46262U,
- 0xa8399191U, 0xa4319595U, 0x37d3e4e4U, 0x8bf27979U,
- 0x32d5e7e7U, 0x438bc8c8U, 0x596e3737U, 0xb7da6d6dU,
- 0x8c018d8dU, 0x64b1d5d5U, 0xd29c4e4eU, 0xe049a9a9U,
- 0xb4d86c6cU, 0xfaac5656U, 0x07f3f4f4U, 0x25cfeaeaU,
- 0xafca6565U, 0x8ef47a7aU, 0xe947aeaeU, 0x18100808U,
- 0xd56fbabaU, 0x88f07878U, 0x6f4a2525U, 0x725c2e2eU,
- 0x24381c1cU, 0xf157a6a6U, 0xc773b4b4U, 0x5197c6c6U,
- 0x23cbe8e8U, 0x7ca1ddddU, 0x9ce87474U, 0x213e1f1fU,
- 0xdd964b4bU, 0xdc61bdbdU, 0x860d8b8bU, 0x850f8a8aU,
- 0x90e07070U, 0x427c3e3eU, 0xc471b5b5U, 0xaacc6666U,
- 0xd8904848U, 0x05060303U, 0x01f7f6f6U, 0x121c0e0eU,
- 0xa3c26161U, 0x5f6a3535U, 0xf9ae5757U, 0xd069b9b9U,
- 0x91178686U, 0x5899c1c1U, 0x273a1d1dU, 0xb9279e9eU,
- 0x38d9e1e1U, 0x13ebf8f8U, 0xb32b9898U, 0x33221111U,
- 0xbbd26969U, 0x70a9d9d9U, 0x89078e8eU, 0xa7339494U,
- 0xb62d9b9bU, 0x223c1e1eU, 0x92158787U, 0x20c9e9e9U,
- 0x4987ceceU, 0xffaa5555U, 0x78502828U, 0x7aa5dfdfU,
- 0x8f038c8cU, 0xf859a1a1U, 0x80098989U, 0x171a0d0dU,
- 0xda65bfbfU, 0x31d7e6e6U, 0xc6844242U, 0xb8d06868U,
- 0xc3824141U, 0xb0299999U, 0x775a2d2dU, 0x111e0f0fU,
- 0xcb7bb0b0U, 0xfca85454U, 0xd66dbbbbU, 0x3a2c1616U,
-};
-static const u32 Te2[256] = {
- 0x63a5c663U, 0x7c84f87cU, 0x7799ee77U, 0x7b8df67bU,
- 0xf20dfff2U, 0x6bbdd66bU, 0x6fb1de6fU, 0xc55491c5U,
- 0x30506030U, 0x01030201U, 0x67a9ce67U, 0x2b7d562bU,
- 0xfe19e7feU, 0xd762b5d7U, 0xabe64dabU, 0x769aec76U,
- 0xca458fcaU, 0x829d1f82U, 0xc94089c9U, 0x7d87fa7dU,
- 0xfa15effaU, 0x59ebb259U, 0x47c98e47U, 0xf00bfbf0U,
- 0xadec41adU, 0xd467b3d4U, 0xa2fd5fa2U, 0xafea45afU,
- 0x9cbf239cU, 0xa4f753a4U, 0x7296e472U, 0xc05b9bc0U,
- 0xb7c275b7U, 0xfd1ce1fdU, 0x93ae3d93U, 0x266a4c26U,
- 0x365a6c36U, 0x3f417e3fU, 0xf702f5f7U, 0xcc4f83ccU,
- 0x345c6834U, 0xa5f451a5U, 0xe534d1e5U, 0xf108f9f1U,
- 0x7193e271U, 0xd873abd8U, 0x31536231U, 0x153f2a15U,
- 0x040c0804U, 0xc75295c7U, 0x23654623U, 0xc35e9dc3U,
- 0x18283018U, 0x96a13796U, 0x050f0a05U, 0x9ab52f9aU,
- 0x07090e07U, 0x12362412U, 0x809b1b80U, 0xe23ddfe2U,
- 0xeb26cdebU, 0x27694e27U, 0xb2cd7fb2U, 0x759fea75U,
- 0x091b1209U, 0x839e1d83U, 0x2c74582cU, 0x1a2e341aU,
- 0x1b2d361bU, 0x6eb2dc6eU, 0x5aeeb45aU, 0xa0fb5ba0U,
- 0x52f6a452U, 0x3b4d763bU, 0xd661b7d6U, 0xb3ce7db3U,
- 0x297b5229U, 0xe33edde3U, 0x2f715e2fU, 0x84971384U,
- 0x53f5a653U, 0xd168b9d1U, 0x00000000U, 0xed2cc1edU,
- 0x20604020U, 0xfc1fe3fcU, 0xb1c879b1U, 0x5bedb65bU,
- 0x6abed46aU, 0xcb468dcbU, 0xbed967beU, 0x394b7239U,
- 0x4ade944aU, 0x4cd4984cU, 0x58e8b058U, 0xcf4a85cfU,
- 0xd06bbbd0U, 0xef2ac5efU, 0xaae54faaU, 0xfb16edfbU,
- 0x43c58643U, 0x4dd79a4dU, 0x33556633U, 0x85941185U,
- 0x45cf8a45U, 0xf910e9f9U, 0x02060402U, 0x7f81fe7fU,
- 0x50f0a050U, 0x3c44783cU, 0x9fba259fU, 0xa8e34ba8U,
- 0x51f3a251U, 0xa3fe5da3U, 0x40c08040U, 0x8f8a058fU,
- 0x92ad3f92U, 0x9dbc219dU, 0x38487038U, 0xf504f1f5U,
- 0xbcdf63bcU, 0xb6c177b6U, 0xda75afdaU, 0x21634221U,
- 0x10302010U, 0xff1ae5ffU, 0xf30efdf3U, 0xd26dbfd2U,
- 0xcd4c81cdU, 0x0c14180cU, 0x13352613U, 0xec2fc3ecU,
- 0x5fe1be5fU, 0x97a23597U, 0x44cc8844U, 0x17392e17U,
- 0xc45793c4U, 0xa7f255a7U, 0x7e82fc7eU, 0x3d477a3dU,
- 0x64acc864U, 0x5de7ba5dU, 0x192b3219U, 0x7395e673U,
- 0x60a0c060U, 0x81981981U, 0x4fd19e4fU, 0xdc7fa3dcU,
- 0x22664422U, 0x2a7e542aU, 0x90ab3b90U, 0x88830b88U,
- 0x46ca8c46U, 0xee29c7eeU, 0xb8d36bb8U, 0x143c2814U,
- 0xde79a7deU, 0x5ee2bc5eU, 0x0b1d160bU, 0xdb76addbU,
- 0xe03bdbe0U, 0x32566432U, 0x3a4e743aU, 0x0a1e140aU,
- 0x49db9249U, 0x060a0c06U, 0x246c4824U, 0x5ce4b85cU,
- 0xc25d9fc2U, 0xd36ebdd3U, 0xacef43acU, 0x62a6c462U,
- 0x91a83991U, 0x95a43195U, 0xe437d3e4U, 0x798bf279U,
- 0xe732d5e7U, 0xc8438bc8U, 0x37596e37U, 0x6db7da6dU,
- 0x8d8c018dU, 0xd564b1d5U, 0x4ed29c4eU, 0xa9e049a9U,
- 0x6cb4d86cU, 0x56faac56U, 0xf407f3f4U, 0xea25cfeaU,
- 0x65afca65U, 0x7a8ef47aU, 0xaee947aeU, 0x08181008U,
- 0xbad56fbaU, 0x7888f078U, 0x256f4a25U, 0x2e725c2eU,
- 0x1c24381cU, 0xa6f157a6U, 0xb4c773b4U, 0xc65197c6U,
- 0xe823cbe8U, 0xdd7ca1ddU, 0x749ce874U, 0x1f213e1fU,
- 0x4bdd964bU, 0xbddc61bdU, 0x8b860d8bU, 0x8a850f8aU,
- 0x7090e070U, 0x3e427c3eU, 0xb5c471b5U, 0x66aacc66U,
- 0x48d89048U, 0x03050603U, 0xf601f7f6U, 0x0e121c0eU,
- 0x61a3c261U, 0x355f6a35U, 0x57f9ae57U, 0xb9d069b9U,
- 0x86911786U, 0xc15899c1U, 0x1d273a1dU, 0x9eb9279eU,
- 0xe138d9e1U, 0xf813ebf8U, 0x98b32b98U, 0x11332211U,
- 0x69bbd269U, 0xd970a9d9U, 0x8e89078eU, 0x94a73394U,
- 0x9bb62d9bU, 0x1e223c1eU, 0x87921587U, 0xe920c9e9U,
- 0xce4987ceU, 0x55ffaa55U, 0x28785028U, 0xdf7aa5dfU,
- 0x8c8f038cU, 0xa1f859a1U, 0x89800989U, 0x0d171a0dU,
- 0xbfda65bfU, 0xe631d7e6U, 0x42c68442U, 0x68b8d068U,
- 0x41c38241U, 0x99b02999U, 0x2d775a2dU, 0x0f111e0fU,
- 0xb0cb7bb0U, 0x54fca854U, 0xbbd66dbbU, 0x163a2c16U,
-};
-static const u32 Te3[256] = {
-
- 0x6363a5c6U, 0x7c7c84f8U, 0x777799eeU, 0x7b7b8df6U,
- 0xf2f20dffU, 0x6b6bbdd6U, 0x6f6fb1deU, 0xc5c55491U,
- 0x30305060U, 0x01010302U, 0x6767a9ceU, 0x2b2b7d56U,
- 0xfefe19e7U, 0xd7d762b5U, 0xababe64dU, 0x76769aecU,
- 0xcaca458fU, 0x82829d1fU, 0xc9c94089U, 0x7d7d87faU,
- 0xfafa15efU, 0x5959ebb2U, 0x4747c98eU, 0xf0f00bfbU,
- 0xadadec41U, 0xd4d467b3U, 0xa2a2fd5fU, 0xafafea45U,
- 0x9c9cbf23U, 0xa4a4f753U, 0x727296e4U, 0xc0c05b9bU,
- 0xb7b7c275U, 0xfdfd1ce1U, 0x9393ae3dU, 0x26266a4cU,
- 0x36365a6cU, 0x3f3f417eU, 0xf7f702f5U, 0xcccc4f83U,
- 0x34345c68U, 0xa5a5f451U, 0xe5e534d1U, 0xf1f108f9U,
- 0x717193e2U, 0xd8d873abU, 0x31315362U, 0x15153f2aU,
- 0x04040c08U, 0xc7c75295U, 0x23236546U, 0xc3c35e9dU,
- 0x18182830U, 0x9696a137U, 0x05050f0aU, 0x9a9ab52fU,
- 0x0707090eU, 0x12123624U, 0x80809b1bU, 0xe2e23ddfU,
- 0xebeb26cdU, 0x2727694eU, 0xb2b2cd7fU, 0x75759feaU,
- 0x09091b12U, 0x83839e1dU, 0x2c2c7458U, 0x1a1a2e34U,
- 0x1b1b2d36U, 0x6e6eb2dcU, 0x5a5aeeb4U, 0xa0a0fb5bU,
- 0x5252f6a4U, 0x3b3b4d76U, 0xd6d661b7U, 0xb3b3ce7dU,
- 0x29297b52U, 0xe3e33eddU, 0x2f2f715eU, 0x84849713U,
- 0x5353f5a6U, 0xd1d168b9U, 0x00000000U, 0xeded2cc1U,
- 0x20206040U, 0xfcfc1fe3U, 0xb1b1c879U, 0x5b5bedb6U,
- 0x6a6abed4U, 0xcbcb468dU, 0xbebed967U, 0x39394b72U,
- 0x4a4ade94U, 0x4c4cd498U, 0x5858e8b0U, 0xcfcf4a85U,
- 0xd0d06bbbU, 0xefef2ac5U, 0xaaaae54fU, 0xfbfb16edU,
- 0x4343c586U, 0x4d4dd79aU, 0x33335566U, 0x85859411U,
- 0x4545cf8aU, 0xf9f910e9U, 0x02020604U, 0x7f7f81feU,
- 0x5050f0a0U, 0x3c3c4478U, 0x9f9fba25U, 0xa8a8e34bU,
- 0x5151f3a2U, 0xa3a3fe5dU, 0x4040c080U, 0x8f8f8a05U,
- 0x9292ad3fU, 0x9d9dbc21U, 0x38384870U, 0xf5f504f1U,
- 0xbcbcdf63U, 0xb6b6c177U, 0xdada75afU, 0x21216342U,
- 0x10103020U, 0xffff1ae5U, 0xf3f30efdU, 0xd2d26dbfU,
- 0xcdcd4c81U, 0x0c0c1418U, 0x13133526U, 0xecec2fc3U,
- 0x5f5fe1beU, 0x9797a235U, 0x4444cc88U, 0x1717392eU,
- 0xc4c45793U, 0xa7a7f255U, 0x7e7e82fcU, 0x3d3d477aU,
- 0x6464acc8U, 0x5d5de7baU, 0x19192b32U, 0x737395e6U,
- 0x6060a0c0U, 0x81819819U, 0x4f4fd19eU, 0xdcdc7fa3U,
- 0x22226644U, 0x2a2a7e54U, 0x9090ab3bU, 0x8888830bU,
- 0x4646ca8cU, 0xeeee29c7U, 0xb8b8d36bU, 0x14143c28U,
- 0xdede79a7U, 0x5e5ee2bcU, 0x0b0b1d16U, 0xdbdb76adU,
- 0xe0e03bdbU, 0x32325664U, 0x3a3a4e74U, 0x0a0a1e14U,
- 0x4949db92U, 0x06060a0cU, 0x24246c48U, 0x5c5ce4b8U,
- 0xc2c25d9fU, 0xd3d36ebdU, 0xacacef43U, 0x6262a6c4U,
- 0x9191a839U, 0x9595a431U, 0xe4e437d3U, 0x79798bf2U,
- 0xe7e732d5U, 0xc8c8438bU, 0x3737596eU, 0x6d6db7daU,
- 0x8d8d8c01U, 0xd5d564b1U, 0x4e4ed29cU, 0xa9a9e049U,
- 0x6c6cb4d8U, 0x5656faacU, 0xf4f407f3U, 0xeaea25cfU,
- 0x6565afcaU, 0x7a7a8ef4U, 0xaeaee947U, 0x08081810U,
- 0xbabad56fU, 0x787888f0U, 0x25256f4aU, 0x2e2e725cU,
- 0x1c1c2438U, 0xa6a6f157U, 0xb4b4c773U, 0xc6c65197U,
- 0xe8e823cbU, 0xdddd7ca1U, 0x74749ce8U, 0x1f1f213eU,
- 0x4b4bdd96U, 0xbdbddc61U, 0x8b8b860dU, 0x8a8a850fU,
- 0x707090e0U, 0x3e3e427cU, 0xb5b5c471U, 0x6666aaccU,
- 0x4848d890U, 0x03030506U, 0xf6f601f7U, 0x0e0e121cU,
- 0x6161a3c2U, 0x35355f6aU, 0x5757f9aeU, 0xb9b9d069U,
- 0x86869117U, 0xc1c15899U, 0x1d1d273aU, 0x9e9eb927U,
- 0xe1e138d9U, 0xf8f813ebU, 0x9898b32bU, 0x11113322U,
- 0x6969bbd2U, 0xd9d970a9U, 0x8e8e8907U, 0x9494a733U,
- 0x9b9bb62dU, 0x1e1e223cU, 0x87879215U, 0xe9e920c9U,
- 0xcece4987U, 0x5555ffaaU, 0x28287850U, 0xdfdf7aa5U,
- 0x8c8c8f03U, 0xa1a1f859U, 0x89898009U, 0x0d0d171aU,
- 0xbfbfda65U, 0xe6e631d7U, 0x4242c684U, 0x6868b8d0U,
- 0x4141c382U, 0x9999b029U, 0x2d2d775aU, 0x0f0f111eU,
- 0xb0b0cb7bU, 0x5454fca8U, 0xbbbbd66dU, 0x16163a2cU,
-};
-static const u32 Te4[256] = {
- 0x63636363U, 0x7c7c7c7cU, 0x77777777U, 0x7b7b7b7bU,
- 0xf2f2f2f2U, 0x6b6b6b6bU, 0x6f6f6f6fU, 0xc5c5c5c5U,
- 0x30303030U, 0x01010101U, 0x67676767U, 0x2b2b2b2bU,
- 0xfefefefeU, 0xd7d7d7d7U, 0xababababU, 0x76767676U,
- 0xcacacacaU, 0x82828282U, 0xc9c9c9c9U, 0x7d7d7d7dU,
- 0xfafafafaU, 0x59595959U, 0x47474747U, 0xf0f0f0f0U,
- 0xadadadadU, 0xd4d4d4d4U, 0xa2a2a2a2U, 0xafafafafU,
- 0x9c9c9c9cU, 0xa4a4a4a4U, 0x72727272U, 0xc0c0c0c0U,
- 0xb7b7b7b7U, 0xfdfdfdfdU, 0x93939393U, 0x26262626U,
- 0x36363636U, 0x3f3f3f3fU, 0xf7f7f7f7U, 0xccccccccU,
- 0x34343434U, 0xa5a5a5a5U, 0xe5e5e5e5U, 0xf1f1f1f1U,
- 0x71717171U, 0xd8d8d8d8U, 0x31313131U, 0x15151515U,
- 0x04040404U, 0xc7c7c7c7U, 0x23232323U, 0xc3c3c3c3U,
- 0x18181818U, 0x96969696U, 0x05050505U, 0x9a9a9a9aU,
- 0x07070707U, 0x12121212U, 0x80808080U, 0xe2e2e2e2U,
- 0xebebebebU, 0x27272727U, 0xb2b2b2b2U, 0x75757575U,
- 0x09090909U, 0x83838383U, 0x2c2c2c2cU, 0x1a1a1a1aU,
- 0x1b1b1b1bU, 0x6e6e6e6eU, 0x5a5a5a5aU, 0xa0a0a0a0U,
- 0x52525252U, 0x3b3b3b3bU, 0xd6d6d6d6U, 0xb3b3b3b3U,
- 0x29292929U, 0xe3e3e3e3U, 0x2f2f2f2fU, 0x84848484U,
- 0x53535353U, 0xd1d1d1d1U, 0x00000000U, 0xededededU,
- 0x20202020U, 0xfcfcfcfcU, 0xb1b1b1b1U, 0x5b5b5b5bU,
- 0x6a6a6a6aU, 0xcbcbcbcbU, 0xbebebebeU, 0x39393939U,
- 0x4a4a4a4aU, 0x4c4c4c4cU, 0x58585858U, 0xcfcfcfcfU,
- 0xd0d0d0d0U, 0xefefefefU, 0xaaaaaaaaU, 0xfbfbfbfbU,
- 0x43434343U, 0x4d4d4d4dU, 0x33333333U, 0x85858585U,
- 0x45454545U, 0xf9f9f9f9U, 0x02020202U, 0x7f7f7f7fU,
- 0x50505050U, 0x3c3c3c3cU, 0x9f9f9f9fU, 0xa8a8a8a8U,
- 0x51515151U, 0xa3a3a3a3U, 0x40404040U, 0x8f8f8f8fU,
- 0x92929292U, 0x9d9d9d9dU, 0x38383838U, 0xf5f5f5f5U,
- 0xbcbcbcbcU, 0xb6b6b6b6U, 0xdadadadaU, 0x21212121U,
- 0x10101010U, 0xffffffffU, 0xf3f3f3f3U, 0xd2d2d2d2U,
- 0xcdcdcdcdU, 0x0c0c0c0cU, 0x13131313U, 0xececececU,
- 0x5f5f5f5fU, 0x97979797U, 0x44444444U, 0x17171717U,
- 0xc4c4c4c4U, 0xa7a7a7a7U, 0x7e7e7e7eU, 0x3d3d3d3dU,
- 0x64646464U, 0x5d5d5d5dU, 0x19191919U, 0x73737373U,
- 0x60606060U, 0x81818181U, 0x4f4f4f4fU, 0xdcdcdcdcU,
- 0x22222222U, 0x2a2a2a2aU, 0x90909090U, 0x88888888U,
- 0x46464646U, 0xeeeeeeeeU, 0xb8b8b8b8U, 0x14141414U,
- 0xdedededeU, 0x5e5e5e5eU, 0x0b0b0b0bU, 0xdbdbdbdbU,
- 0xe0e0e0e0U, 0x32323232U, 0x3a3a3a3aU, 0x0a0a0a0aU,
- 0x49494949U, 0x06060606U, 0x24242424U, 0x5c5c5c5cU,
- 0xc2c2c2c2U, 0xd3d3d3d3U, 0xacacacacU, 0x62626262U,
- 0x91919191U, 0x95959595U, 0xe4e4e4e4U, 0x79797979U,
- 0xe7e7e7e7U, 0xc8c8c8c8U, 0x37373737U, 0x6d6d6d6dU,
- 0x8d8d8d8dU, 0xd5d5d5d5U, 0x4e4e4e4eU, 0xa9a9a9a9U,
- 0x6c6c6c6cU, 0x56565656U, 0xf4f4f4f4U, 0xeaeaeaeaU,
- 0x65656565U, 0x7a7a7a7aU, 0xaeaeaeaeU, 0x08080808U,
- 0xbabababaU, 0x78787878U, 0x25252525U, 0x2e2e2e2eU,
- 0x1c1c1c1cU, 0xa6a6a6a6U, 0xb4b4b4b4U, 0xc6c6c6c6U,
- 0xe8e8e8e8U, 0xddddddddU, 0x74747474U, 0x1f1f1f1fU,
- 0x4b4b4b4bU, 0xbdbdbdbdU, 0x8b8b8b8bU, 0x8a8a8a8aU,
- 0x70707070U, 0x3e3e3e3eU, 0xb5b5b5b5U, 0x66666666U,
- 0x48484848U, 0x03030303U, 0xf6f6f6f6U, 0x0e0e0e0eU,
- 0x61616161U, 0x35353535U, 0x57575757U, 0xb9b9b9b9U,
- 0x86868686U, 0xc1c1c1c1U, 0x1d1d1d1dU, 0x9e9e9e9eU,
- 0xe1e1e1e1U, 0xf8f8f8f8U, 0x98989898U, 0x11111111U,
- 0x69696969U, 0xd9d9d9d9U, 0x8e8e8e8eU, 0x94949494U,
- 0x9b9b9b9bU, 0x1e1e1e1eU, 0x87878787U, 0xe9e9e9e9U,
- 0xcecececeU, 0x55555555U, 0x28282828U, 0xdfdfdfdfU,
- 0x8c8c8c8cU, 0xa1a1a1a1U, 0x89898989U, 0x0d0d0d0dU,
- 0xbfbfbfbfU, 0xe6e6e6e6U, 0x42424242U, 0x68686868U,
- 0x41414141U, 0x99999999U, 0x2d2d2d2dU, 0x0f0f0f0fU,
- 0xb0b0b0b0U, 0x54545454U, 0xbbbbbbbbU, 0x16161616U,
-};
-static const u32 Td0[256] = {
- 0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U,
- 0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U,
- 0x2030fa55U, 0xad766df6U, 0x88cc7691U, 0xf5024c25U,
- 0x4fe5d7fcU, 0xc52acbd7U, 0x26354480U, 0xb562a38fU,
- 0xdeb15a49U, 0x25ba1b67U, 0x45ea0e98U, 0x5dfec0e1U,
- 0xc32f7502U, 0x814cf012U, 0x8d4697a3U, 0x6bd3f9c6U,
- 0x038f5fe7U, 0x15929c95U, 0xbf6d7aebU, 0x955259daU,
- 0xd4be832dU, 0x587421d3U, 0x49e06929U, 0x8ec9c844U,
- 0x75c2896aU, 0xf48e7978U, 0x99583e6bU, 0x27b971ddU,
- 0xbee14fb6U, 0xf088ad17U, 0xc920ac66U, 0x7dce3ab4U,
- 0x63df4a18U, 0xe51a3182U, 0x97513360U, 0x62537f45U,
- 0xb16477e0U, 0xbb6bae84U, 0xfe81a01cU, 0xf9082b94U,
- 0x70486858U, 0x8f45fd19U, 0x94de6c87U, 0x527bf8b7U,
- 0xab73d323U, 0x724b02e2U, 0xe31f8f57U, 0x6655ab2aU,
- 0xb2eb2807U, 0x2fb5c203U, 0x86c57b9aU, 0xd33708a5U,
- 0x302887f2U, 0x23bfa5b2U, 0x02036abaU, 0xed16825cU,
- 0x8acf1c2bU, 0xa779b492U, 0xf307f2f0U, 0x4e69e2a1U,
- 0x65daf4cdU, 0x0605bed5U, 0xd134621fU, 0xc4a6fe8aU,
- 0x342e539dU, 0xa2f355a0U, 0x058ae132U, 0xa4f6eb75U,
- 0x0b83ec39U, 0x4060efaaU, 0x5e719f06U, 0xbd6e1051U,
- 0x3e218af9U, 0x96dd063dU, 0xdd3e05aeU, 0x4de6bd46U,
- 0x91548db5U, 0x71c45d05U, 0x0406d46fU, 0x605015ffU,
- 0x1998fb24U, 0xd6bde997U, 0x894043ccU, 0x67d99e77U,
- 0xb0e842bdU, 0x07898b88U, 0xe7195b38U, 0x79c8eedbU,
- 0xa17c0a47U, 0x7c420fe9U, 0xf8841ec9U, 0x00000000U,
- 0x09808683U, 0x322bed48U, 0x1e1170acU, 0x6c5a724eU,
- 0xfd0efffbU, 0x0f853856U, 0x3daed51eU, 0x362d3927U,
- 0x0a0fd964U, 0x685ca621U, 0x9b5b54d1U, 0x24362e3aU,
- 0x0c0a67b1U, 0x9357e70fU, 0xb4ee96d2U, 0x1b9b919eU,
- 0x80c0c54fU, 0x61dc20a2U, 0x5a774b69U, 0x1c121a16U,
- 0xe293ba0aU, 0xc0a02ae5U, 0x3c22e043U, 0x121b171dU,
- 0x0e090d0bU, 0xf28bc7adU, 0x2db6a8b9U, 0x141ea9c8U,
- 0x57f11985U, 0xaf75074cU, 0xee99ddbbU, 0xa37f60fdU,
- 0xf701269fU, 0x5c72f5bcU, 0x44663bc5U, 0x5bfb7e34U,
- 0x8b432976U, 0xcb23c6dcU, 0xb6edfc68U, 0xb8e4f163U,
- 0xd731dccaU, 0x42638510U, 0x13972240U, 0x84c61120U,
- 0x854a247dU, 0xd2bb3df8U, 0xaef93211U, 0xc729a16dU,
- 0x1d9e2f4bU, 0xdcb230f3U, 0x0d8652ecU, 0x77c1e3d0U,
- 0x2bb3166cU, 0xa970b999U, 0x119448faU, 0x47e96422U,
- 0xa8fc8cc4U, 0xa0f03f1aU, 0x567d2cd8U, 0x223390efU,
- 0x87494ec7U, 0xd938d1c1U, 0x8ccaa2feU, 0x98d40b36U,
- 0xa6f581cfU, 0xa57ade28U, 0xdab78e26U, 0x3fadbfa4U,
- 0x2c3a9de4U, 0x5078920dU, 0x6a5fcc9bU, 0x547e4662U,
- 0xf68d13c2U, 0x90d8b8e8U, 0x2e39f75eU, 0x82c3aff5U,
- 0x9f5d80beU, 0x69d0937cU, 0x6fd52da9U, 0xcf2512b3U,
- 0xc8ac993bU, 0x10187da7U, 0xe89c636eU, 0xdb3bbb7bU,
- 0xcd267809U, 0x6e5918f4U, 0xec9ab701U, 0x834f9aa8U,
- 0xe6956e65U, 0xaaffe67eU, 0x21bccf08U, 0xef15e8e6U,
- 0xbae79bd9U, 0x4a6f36ceU, 0xea9f09d4U, 0x29b07cd6U,
- 0x31a4b2afU, 0x2a3f2331U, 0xc6a59430U, 0x35a266c0U,
- 0x744ebc37U, 0xfc82caa6U, 0xe090d0b0U, 0x33a7d815U,
- 0xf104984aU, 0x41ecdaf7U, 0x7fcd500eU, 0x1791f62fU,
- 0x764dd68dU, 0x43efb04dU, 0xccaa4d54U, 0xe49604dfU,
- 0x9ed1b5e3U, 0x4c6a881bU, 0xc12c1fb8U, 0x4665517fU,
- 0x9d5eea04U, 0x018c355dU, 0xfa877473U, 0xfb0b412eU,
- 0xb3671d5aU, 0x92dbd252U, 0xe9105633U, 0x6dd64713U,
- 0x9ad7618cU, 0x37a10c7aU, 0x59f8148eU, 0xeb133c89U,
- 0xcea927eeU, 0xb761c935U, 0xe11ce5edU, 0x7a47b13cU,
- 0x9cd2df59U, 0x55f2733fU, 0x1814ce79U, 0x73c737bfU,
- 0x53f7cdeaU, 0x5ffdaa5bU, 0xdf3d6f14U, 0x7844db86U,
- 0xcaaff381U, 0xb968c43eU, 0x3824342cU, 0xc2a3405fU,
- 0x161dc372U, 0xbce2250cU, 0x283c498bU, 0xff0d9541U,
- 0x39a80171U, 0x080cb3deU, 0xd8b4e49cU, 0x6456c190U,
- 0x7bcb8461U, 0xd532b670U, 0x486c5c74U, 0xd0b85742U,
-};
-static const u32 Td1[256] = {
- 0x5051f4a7U, 0x537e4165U, 0xc31a17a4U, 0x963a275eU,
- 0xcb3bab6bU, 0xf11f9d45U, 0xabacfa58U, 0x934be303U,
- 0x552030faU, 0xf6ad766dU, 0x9188cc76U, 0x25f5024cU,
- 0xfc4fe5d7U, 0xd7c52acbU, 0x80263544U, 0x8fb562a3U,
- 0x49deb15aU, 0x6725ba1bU, 0x9845ea0eU, 0xe15dfec0U,
- 0x02c32f75U, 0x12814cf0U, 0xa38d4697U, 0xc66bd3f9U,
- 0xe7038f5fU, 0x9515929cU, 0xebbf6d7aU, 0xda955259U,
- 0x2dd4be83U, 0xd3587421U, 0x2949e069U, 0x448ec9c8U,
- 0x6a75c289U, 0x78f48e79U, 0x6b99583eU, 0xdd27b971U,
- 0xb6bee14fU, 0x17f088adU, 0x66c920acU, 0xb47dce3aU,
- 0x1863df4aU, 0x82e51a31U, 0x60975133U, 0x4562537fU,
- 0xe0b16477U, 0x84bb6baeU, 0x1cfe81a0U, 0x94f9082bU,
- 0x58704868U, 0x198f45fdU, 0x8794de6cU, 0xb7527bf8U,
- 0x23ab73d3U, 0xe2724b02U, 0x57e31f8fU, 0x2a6655abU,
- 0x07b2eb28U, 0x032fb5c2U, 0x9a86c57bU, 0xa5d33708U,
- 0xf2302887U, 0xb223bfa5U, 0xba02036aU, 0x5ced1682U,
- 0x2b8acf1cU, 0x92a779b4U, 0xf0f307f2U, 0xa14e69e2U,
- 0xcd65daf4U, 0xd50605beU, 0x1fd13462U, 0x8ac4a6feU,
- 0x9d342e53U, 0xa0a2f355U, 0x32058ae1U, 0x75a4f6ebU,
- 0x390b83ecU, 0xaa4060efU, 0x065e719fU, 0x51bd6e10U,
- 0xf93e218aU, 0x3d96dd06U, 0xaedd3e05U, 0x464de6bdU,
- 0xb591548dU, 0x0571c45dU, 0x6f0406d4U, 0xff605015U,
- 0x241998fbU, 0x97d6bde9U, 0xcc894043U, 0x7767d99eU,
- 0xbdb0e842U, 0x8807898bU, 0x38e7195bU, 0xdb79c8eeU,
- 0x47a17c0aU, 0xe97c420fU, 0xc9f8841eU, 0x00000000U,
- 0x83098086U, 0x48322bedU, 0xac1e1170U, 0x4e6c5a72U,
- 0xfbfd0effU, 0x560f8538U, 0x1e3daed5U, 0x27362d39U,
- 0x640a0fd9U, 0x21685ca6U, 0xd19b5b54U, 0x3a24362eU,
- 0xb10c0a67U, 0x0f9357e7U, 0xd2b4ee96U, 0x9e1b9b91U,
- 0x4f80c0c5U, 0xa261dc20U, 0x695a774bU, 0x161c121aU,
- 0x0ae293baU, 0xe5c0a02aU, 0x433c22e0U, 0x1d121b17U,
- 0x0b0e090dU, 0xadf28bc7U, 0xb92db6a8U, 0xc8141ea9U,
- 0x8557f119U, 0x4caf7507U, 0xbbee99ddU, 0xfda37f60U,
- 0x9ff70126U, 0xbc5c72f5U, 0xc544663bU, 0x345bfb7eU,
- 0x768b4329U, 0xdccb23c6U, 0x68b6edfcU, 0x63b8e4f1U,
- 0xcad731dcU, 0x10426385U, 0x40139722U, 0x2084c611U,
- 0x7d854a24U, 0xf8d2bb3dU, 0x11aef932U, 0x6dc729a1U,
- 0x4b1d9e2fU, 0xf3dcb230U, 0xec0d8652U, 0xd077c1e3U,
- 0x6c2bb316U, 0x99a970b9U, 0xfa119448U, 0x2247e964U,
- 0xc4a8fc8cU, 0x1aa0f03fU, 0xd8567d2cU, 0xef223390U,
- 0xc787494eU, 0xc1d938d1U, 0xfe8ccaa2U, 0x3698d40bU,
- 0xcfa6f581U, 0x28a57adeU, 0x26dab78eU, 0xa43fadbfU,
- 0xe42c3a9dU, 0x0d507892U, 0x9b6a5fccU, 0x62547e46U,
- 0xc2f68d13U, 0xe890d8b8U, 0x5e2e39f7U, 0xf582c3afU,
- 0xbe9f5d80U, 0x7c69d093U, 0xa96fd52dU, 0xb3cf2512U,
- 0x3bc8ac99U, 0xa710187dU, 0x6ee89c63U, 0x7bdb3bbbU,
- 0x09cd2678U, 0xf46e5918U, 0x01ec9ab7U, 0xa8834f9aU,
- 0x65e6956eU, 0x7eaaffe6U, 0x0821bccfU, 0xe6ef15e8U,
- 0xd9bae79bU, 0xce4a6f36U, 0xd4ea9f09U, 0xd629b07cU,
- 0xaf31a4b2U, 0x312a3f23U, 0x30c6a594U, 0xc035a266U,
- 0x37744ebcU, 0xa6fc82caU, 0xb0e090d0U, 0x1533a7d8U,
- 0x4af10498U, 0xf741ecdaU, 0x0e7fcd50U, 0x2f1791f6U,
- 0x8d764dd6U, 0x4d43efb0U, 0x54ccaa4dU, 0xdfe49604U,
- 0xe39ed1b5U, 0x1b4c6a88U, 0xb8c12c1fU, 0x7f466551U,
- 0x049d5eeaU, 0x5d018c35U, 0x73fa8774U, 0x2efb0b41U,
- 0x5ab3671dU, 0x5292dbd2U, 0x33e91056U, 0x136dd647U,
- 0x8c9ad761U, 0x7a37a10cU, 0x8e59f814U, 0x89eb133cU,
- 0xeecea927U, 0x35b761c9U, 0xede11ce5U, 0x3c7a47b1U,
- 0x599cd2dfU, 0x3f55f273U, 0x791814ceU, 0xbf73c737U,
- 0xea53f7cdU, 0x5b5ffdaaU, 0x14df3d6fU, 0x867844dbU,
- 0x81caaff3U, 0x3eb968c4U, 0x2c382434U, 0x5fc2a340U,
- 0x72161dc3U, 0x0cbce225U, 0x8b283c49U, 0x41ff0d95U,
- 0x7139a801U, 0xde080cb3U, 0x9cd8b4e4U, 0x906456c1U,
- 0x617bcb84U, 0x70d532b6U, 0x74486c5cU, 0x42d0b857U,
-};
-static const u32 Td2[256] = {
- 0xa75051f4U, 0x65537e41U, 0xa4c31a17U, 0x5e963a27U,
- 0x6bcb3babU, 0x45f11f9dU, 0x58abacfaU, 0x03934be3U,
- 0xfa552030U, 0x6df6ad76U, 0x769188ccU, 0x4c25f502U,
- 0xd7fc4fe5U, 0xcbd7c52aU, 0x44802635U, 0xa38fb562U,
- 0x5a49deb1U, 0x1b6725baU, 0x0e9845eaU, 0xc0e15dfeU,
- 0x7502c32fU, 0xf012814cU, 0x97a38d46U, 0xf9c66bd3U,
- 0x5fe7038fU, 0x9c951592U, 0x7aebbf6dU, 0x59da9552U,
- 0x832dd4beU, 0x21d35874U, 0x692949e0U, 0xc8448ec9U,
- 0x896a75c2U, 0x7978f48eU, 0x3e6b9958U, 0x71dd27b9U,
- 0x4fb6bee1U, 0xad17f088U, 0xac66c920U, 0x3ab47dceU,
- 0x4a1863dfU, 0x3182e51aU, 0x33609751U, 0x7f456253U,
- 0x77e0b164U, 0xae84bb6bU, 0xa01cfe81U, 0x2b94f908U,
- 0x68587048U, 0xfd198f45U, 0x6c8794deU, 0xf8b7527bU,
- 0xd323ab73U, 0x02e2724bU, 0x8f57e31fU, 0xab2a6655U,
- 0x2807b2ebU, 0xc2032fb5U, 0x7b9a86c5U, 0x08a5d337U,
- 0x87f23028U, 0xa5b223bfU, 0x6aba0203U, 0x825ced16U,
- 0x1c2b8acfU, 0xb492a779U, 0xf2f0f307U, 0xe2a14e69U,
- 0xf4cd65daU, 0xbed50605U, 0x621fd134U, 0xfe8ac4a6U,
- 0x539d342eU, 0x55a0a2f3U, 0xe132058aU, 0xeb75a4f6U,
- 0xec390b83U, 0xefaa4060U, 0x9f065e71U, 0x1051bd6eU,
-
- 0x8af93e21U, 0x063d96ddU, 0x05aedd3eU, 0xbd464de6U,
- 0x8db59154U, 0x5d0571c4U, 0xd46f0406U, 0x15ff6050U,
- 0xfb241998U, 0xe997d6bdU, 0x43cc8940U, 0x9e7767d9U,
- 0x42bdb0e8U, 0x8b880789U, 0x5b38e719U, 0xeedb79c8U,
- 0x0a47a17cU, 0x0fe97c42U, 0x1ec9f884U, 0x00000000U,
- 0x86830980U, 0xed48322bU, 0x70ac1e11U, 0x724e6c5aU,
- 0xfffbfd0eU, 0x38560f85U, 0xd51e3daeU, 0x3927362dU,
- 0xd9640a0fU, 0xa621685cU, 0x54d19b5bU, 0x2e3a2436U,
- 0x67b10c0aU, 0xe70f9357U, 0x96d2b4eeU, 0x919e1b9bU,
- 0xc54f80c0U, 0x20a261dcU, 0x4b695a77U, 0x1a161c12U,
- 0xba0ae293U, 0x2ae5c0a0U, 0xe0433c22U, 0x171d121bU,
- 0x0d0b0e09U, 0xc7adf28bU, 0xa8b92db6U, 0xa9c8141eU,
- 0x198557f1U, 0x074caf75U, 0xddbbee99U, 0x60fda37fU,
- 0x269ff701U, 0xf5bc5c72U, 0x3bc54466U, 0x7e345bfbU,
- 0x29768b43U, 0xc6dccb23U, 0xfc68b6edU, 0xf163b8e4U,
- 0xdccad731U, 0x85104263U, 0x22401397U, 0x112084c6U,
- 0x247d854aU, 0x3df8d2bbU, 0x3211aef9U, 0xa16dc729U,
- 0x2f4b1d9eU, 0x30f3dcb2U, 0x52ec0d86U, 0xe3d077c1U,
- 0x166c2bb3U, 0xb999a970U, 0x48fa1194U, 0x642247e9U,
- 0x8cc4a8fcU, 0x3f1aa0f0U, 0x2cd8567dU, 0x90ef2233U,
- 0x4ec78749U, 0xd1c1d938U, 0xa2fe8ccaU, 0x0b3698d4U,
- 0x81cfa6f5U, 0xde28a57aU, 0x8e26dab7U, 0xbfa43fadU,
- 0x9de42c3aU, 0x920d5078U, 0xcc9b6a5fU, 0x4662547eU,
- 0x13c2f68dU, 0xb8e890d8U, 0xf75e2e39U, 0xaff582c3U,
- 0x80be9f5dU, 0x937c69d0U, 0x2da96fd5U, 0x12b3cf25U,
- 0x993bc8acU, 0x7da71018U, 0x636ee89cU, 0xbb7bdb3bU,
- 0x7809cd26U, 0x18f46e59U, 0xb701ec9aU, 0x9aa8834fU,
- 0x6e65e695U, 0xe67eaaffU, 0xcf0821bcU, 0xe8e6ef15U,
- 0x9bd9bae7U, 0x36ce4a6fU, 0x09d4ea9fU, 0x7cd629b0U,
- 0xb2af31a4U, 0x23312a3fU, 0x9430c6a5U, 0x66c035a2U,
- 0xbc37744eU, 0xcaa6fc82U, 0xd0b0e090U, 0xd81533a7U,
- 0x984af104U, 0xdaf741ecU, 0x500e7fcdU, 0xf62f1791U,
- 0xd68d764dU, 0xb04d43efU, 0x4d54ccaaU, 0x04dfe496U,
- 0xb5e39ed1U, 0x881b4c6aU, 0x1fb8c12cU, 0x517f4665U,
- 0xea049d5eU, 0x355d018cU, 0x7473fa87U, 0x412efb0bU,
- 0x1d5ab367U, 0xd25292dbU, 0x5633e910U, 0x47136dd6U,
- 0x618c9ad7U, 0x0c7a37a1U, 0x148e59f8U, 0x3c89eb13U,
- 0x27eecea9U, 0xc935b761U, 0xe5ede11cU, 0xb13c7a47U,
- 0xdf599cd2U, 0x733f55f2U, 0xce791814U, 0x37bf73c7U,
- 0xcdea53f7U, 0xaa5b5ffdU, 0x6f14df3dU, 0xdb867844U,
- 0xf381caafU, 0xc43eb968U, 0x342c3824U, 0x405fc2a3U,
- 0xc372161dU, 0x250cbce2U, 0x498b283cU, 0x9541ff0dU,
- 0x017139a8U, 0xb3de080cU, 0xe49cd8b4U, 0xc1906456U,
- 0x84617bcbU, 0xb670d532U, 0x5c74486cU, 0x5742d0b8U,
-};
-static const u32 Td3[256] = {
- 0xf4a75051U, 0x4165537eU, 0x17a4c31aU, 0x275e963aU,
- 0xab6bcb3bU, 0x9d45f11fU, 0xfa58abacU, 0xe303934bU,
- 0x30fa5520U, 0x766df6adU, 0xcc769188U, 0x024c25f5U,
- 0xe5d7fc4fU, 0x2acbd7c5U, 0x35448026U, 0x62a38fb5U,
- 0xb15a49deU, 0xba1b6725U, 0xea0e9845U, 0xfec0e15dU,
- 0x2f7502c3U, 0x4cf01281U, 0x4697a38dU, 0xd3f9c66bU,
- 0x8f5fe703U, 0x929c9515U, 0x6d7aebbfU, 0x5259da95U,
- 0xbe832dd4U, 0x7421d358U, 0xe0692949U, 0xc9c8448eU,
- 0xc2896a75U, 0x8e7978f4U, 0x583e6b99U, 0xb971dd27U,
- 0xe14fb6beU, 0x88ad17f0U, 0x20ac66c9U, 0xce3ab47dU,
- 0xdf4a1863U, 0x1a3182e5U, 0x51336097U, 0x537f4562U,
- 0x6477e0b1U, 0x6bae84bbU, 0x81a01cfeU, 0x082b94f9U,
- 0x48685870U, 0x45fd198fU, 0xde6c8794U, 0x7bf8b752U,
- 0x73d323abU, 0x4b02e272U, 0x1f8f57e3U, 0x55ab2a66U,
- 0xeb2807b2U, 0xb5c2032fU, 0xc57b9a86U, 0x3708a5d3U,
- 0x2887f230U, 0xbfa5b223U, 0x036aba02U, 0x16825cedU,
- 0xcf1c2b8aU, 0x79b492a7U, 0x07f2f0f3U, 0x69e2a14eU,
- 0xdaf4cd65U, 0x05bed506U, 0x34621fd1U, 0xa6fe8ac4U,
- 0x2e539d34U, 0xf355a0a2U, 0x8ae13205U, 0xf6eb75a4U,
- 0x83ec390bU, 0x60efaa40U, 0x719f065eU, 0x6e1051bdU,
- 0x218af93eU, 0xdd063d96U, 0x3e05aeddU, 0xe6bd464dU,
- 0x548db591U, 0xc45d0571U, 0x06d46f04U, 0x5015ff60U,
- 0x98fb2419U, 0xbde997d6U, 0x4043cc89U, 0xd99e7767U,
- 0xe842bdb0U, 0x898b8807U, 0x195b38e7U, 0xc8eedb79U,
- 0x7c0a47a1U, 0x420fe97cU, 0x841ec9f8U, 0x00000000U,
- 0x80868309U, 0x2bed4832U, 0x1170ac1eU, 0x5a724e6cU,
- 0x0efffbfdU, 0x8538560fU, 0xaed51e3dU, 0x2d392736U,
- 0x0fd9640aU, 0x5ca62168U, 0x5b54d19bU, 0x362e3a24U,
- 0x0a67b10cU, 0x57e70f93U, 0xee96d2b4U, 0x9b919e1bU,
- 0xc0c54f80U, 0xdc20a261U, 0x774b695aU, 0x121a161cU,
- 0x93ba0ae2U, 0xa02ae5c0U, 0x22e0433cU, 0x1b171d12U,
- 0x090d0b0eU, 0x8bc7adf2U, 0xb6a8b92dU, 0x1ea9c814U,
- 0xf1198557U, 0x75074cafU, 0x99ddbbeeU, 0x7f60fda3U,
- 0x01269ff7U, 0x72f5bc5cU, 0x663bc544U, 0xfb7e345bU,
- 0x4329768bU, 0x23c6dccbU, 0xedfc68b6U, 0xe4f163b8U,
- 0x31dccad7U, 0x63851042U, 0x97224013U, 0xc6112084U,
- 0x4a247d85U, 0xbb3df8d2U, 0xf93211aeU, 0x29a16dc7U,
- 0x9e2f4b1dU, 0xb230f3dcU, 0x8652ec0dU, 0xc1e3d077U,
- 0xb3166c2bU, 0x70b999a9U, 0x9448fa11U, 0xe9642247U,
- 0xfc8cc4a8U, 0xf03f1aa0U, 0x7d2cd856U, 0x3390ef22U,
- 0x494ec787U, 0x38d1c1d9U, 0xcaa2fe8cU, 0xd40b3698U,
- 0xf581cfa6U, 0x7ade28a5U, 0xb78e26daU, 0xadbfa43fU,
- 0x3a9de42cU, 0x78920d50U, 0x5fcc9b6aU, 0x7e466254U,
- 0x8d13c2f6U, 0xd8b8e890U, 0x39f75e2eU, 0xc3aff582U,
- 0x5d80be9fU, 0xd0937c69U, 0xd52da96fU, 0x2512b3cfU,
- 0xac993bc8U, 0x187da710U, 0x9c636ee8U, 0x3bbb7bdbU,
- 0x267809cdU, 0x5918f46eU, 0x9ab701ecU, 0x4f9aa883U,
- 0x956e65e6U, 0xffe67eaaU, 0xbccf0821U, 0x15e8e6efU,
- 0xe79bd9baU, 0x6f36ce4aU, 0x9f09d4eaU, 0xb07cd629U,
- 0xa4b2af31U, 0x3f23312aU, 0xa59430c6U, 0xa266c035U,
- 0x4ebc3774U, 0x82caa6fcU, 0x90d0b0e0U, 0xa7d81533U,
- 0x04984af1U, 0xecdaf741U, 0xcd500e7fU, 0x91f62f17U,
- 0x4dd68d76U, 0xefb04d43U, 0xaa4d54ccU, 0x9604dfe4U,
- 0xd1b5e39eU, 0x6a881b4cU, 0x2c1fb8c1U, 0x65517f46U,
- 0x5eea049dU, 0x8c355d01U, 0x877473faU, 0x0b412efbU,
- 0x671d5ab3U, 0xdbd25292U, 0x105633e9U, 0xd647136dU,
- 0xd7618c9aU, 0xa10c7a37U, 0xf8148e59U, 0x133c89ebU,
- 0xa927eeceU, 0x61c935b7U, 0x1ce5ede1U, 0x47b13c7aU,
- 0xd2df599cU, 0xf2733f55U, 0x14ce7918U, 0xc737bf73U,
- 0xf7cdea53U, 0xfdaa5b5fU, 0x3d6f14dfU, 0x44db8678U,
- 0xaff381caU, 0x68c43eb9U, 0x24342c38U, 0xa3405fc2U,
- 0x1dc37216U, 0xe2250cbcU, 0x3c498b28U, 0x0d9541ffU,
- 0xa8017139U, 0x0cb3de08U, 0xb4e49cd8U, 0x56c19064U,
- 0xcb84617bU, 0x32b670d5U, 0x6c5c7448U, 0xb85742d0U,
-};
-static const u32 Td4[256] = {
- 0x52525252U, 0x09090909U, 0x6a6a6a6aU, 0xd5d5d5d5U,
- 0x30303030U, 0x36363636U, 0xa5a5a5a5U, 0x38383838U,
- 0xbfbfbfbfU, 0x40404040U, 0xa3a3a3a3U, 0x9e9e9e9eU,
- 0x81818181U, 0xf3f3f3f3U, 0xd7d7d7d7U, 0xfbfbfbfbU,
- 0x7c7c7c7cU, 0xe3e3e3e3U, 0x39393939U, 0x82828282U,
- 0x9b9b9b9bU, 0x2f2f2f2fU, 0xffffffffU, 0x87878787U,
- 0x34343434U, 0x8e8e8e8eU, 0x43434343U, 0x44444444U,
- 0xc4c4c4c4U, 0xdedededeU, 0xe9e9e9e9U, 0xcbcbcbcbU,
- 0x54545454U, 0x7b7b7b7bU, 0x94949494U, 0x32323232U,
- 0xa6a6a6a6U, 0xc2c2c2c2U, 0x23232323U, 0x3d3d3d3dU,
- 0xeeeeeeeeU, 0x4c4c4c4cU, 0x95959595U, 0x0b0b0b0bU,
- 0x42424242U, 0xfafafafaU, 0xc3c3c3c3U, 0x4e4e4e4eU,
- 0x08080808U, 0x2e2e2e2eU, 0xa1a1a1a1U, 0x66666666U,
- 0x28282828U, 0xd9d9d9d9U, 0x24242424U, 0xb2b2b2b2U,
- 0x76767676U, 0x5b5b5b5bU, 0xa2a2a2a2U, 0x49494949U,
- 0x6d6d6d6dU, 0x8b8b8b8bU, 0xd1d1d1d1U, 0x25252525U,
- 0x72727272U, 0xf8f8f8f8U, 0xf6f6f6f6U, 0x64646464U,
- 0x86868686U, 0x68686868U, 0x98989898U, 0x16161616U,
- 0xd4d4d4d4U, 0xa4a4a4a4U, 0x5c5c5c5cU, 0xccccccccU,
- 0x5d5d5d5dU, 0x65656565U, 0xb6b6b6b6U, 0x92929292U,
- 0x6c6c6c6cU, 0x70707070U, 0x48484848U, 0x50505050U,
- 0xfdfdfdfdU, 0xededededU, 0xb9b9b9b9U, 0xdadadadaU,
- 0x5e5e5e5eU, 0x15151515U, 0x46464646U, 0x57575757U,
- 0xa7a7a7a7U, 0x8d8d8d8dU, 0x9d9d9d9dU, 0x84848484U,
- 0x90909090U, 0xd8d8d8d8U, 0xababababU, 0x00000000U,
- 0x8c8c8c8cU, 0xbcbcbcbcU, 0xd3d3d3d3U, 0x0a0a0a0aU,
- 0xf7f7f7f7U, 0xe4e4e4e4U, 0x58585858U, 0x05050505U,
- 0xb8b8b8b8U, 0xb3b3b3b3U, 0x45454545U, 0x06060606U,
- 0xd0d0d0d0U, 0x2c2c2c2cU, 0x1e1e1e1eU, 0x8f8f8f8fU,
- 0xcacacacaU, 0x3f3f3f3fU, 0x0f0f0f0fU, 0x02020202U,
- 0xc1c1c1c1U, 0xafafafafU, 0xbdbdbdbdU, 0x03030303U,
- 0x01010101U, 0x13131313U, 0x8a8a8a8aU, 0x6b6b6b6bU,
- 0x3a3a3a3aU, 0x91919191U, 0x11111111U, 0x41414141U,
- 0x4f4f4f4fU, 0x67676767U, 0xdcdcdcdcU, 0xeaeaeaeaU,
- 0x97979797U, 0xf2f2f2f2U, 0xcfcfcfcfU, 0xcecececeU,
- 0xf0f0f0f0U, 0xb4b4b4b4U, 0xe6e6e6e6U, 0x73737373U,
- 0x96969696U, 0xacacacacU, 0x74747474U, 0x22222222U,
- 0xe7e7e7e7U, 0xadadadadU, 0x35353535U, 0x85858585U,
- 0xe2e2e2e2U, 0xf9f9f9f9U, 0x37373737U, 0xe8e8e8e8U,
- 0x1c1c1c1cU, 0x75757575U, 0xdfdfdfdfU, 0x6e6e6e6eU,
- 0x47474747U, 0xf1f1f1f1U, 0x1a1a1a1aU, 0x71717171U,
- 0x1d1d1d1dU, 0x29292929U, 0xc5c5c5c5U, 0x89898989U,
- 0x6f6f6f6fU, 0xb7b7b7b7U, 0x62626262U, 0x0e0e0e0eU,
- 0xaaaaaaaaU, 0x18181818U, 0xbebebebeU, 0x1b1b1b1bU,
- 0xfcfcfcfcU, 0x56565656U, 0x3e3e3e3eU, 0x4b4b4b4bU,
- 0xc6c6c6c6U, 0xd2d2d2d2U, 0x79797979U, 0x20202020U,
- 0x9a9a9a9aU, 0xdbdbdbdbU, 0xc0c0c0c0U, 0xfefefefeU,
- 0x78787878U, 0xcdcdcdcdU, 0x5a5a5a5aU, 0xf4f4f4f4U,
- 0x1f1f1f1fU, 0xddddddddU, 0xa8a8a8a8U, 0x33333333U,
- 0x88888888U, 0x07070707U, 0xc7c7c7c7U, 0x31313131U,
- 0xb1b1b1b1U, 0x12121212U, 0x10101010U, 0x59595959U,
- 0x27272727U, 0x80808080U, 0xececececU, 0x5f5f5f5fU,
- 0x60606060U, 0x51515151U, 0x7f7f7f7fU, 0xa9a9a9a9U,
- 0x19191919U, 0xb5b5b5b5U, 0x4a4a4a4aU, 0x0d0d0d0dU,
- 0x2d2d2d2dU, 0xe5e5e5e5U, 0x7a7a7a7aU, 0x9f9f9f9fU,
- 0x93939393U, 0xc9c9c9c9U, 0x9c9c9c9cU, 0xefefefefU,
- 0xa0a0a0a0U, 0xe0e0e0e0U, 0x3b3b3b3bU, 0x4d4d4d4dU,
- 0xaeaeaeaeU, 0x2a2a2a2aU, 0xf5f5f5f5U, 0xb0b0b0b0U,
- 0xc8c8c8c8U, 0xebebebebU, 0xbbbbbbbbU, 0x3c3c3c3cU,
- 0x83838383U, 0x53535353U, 0x99999999U, 0x61616161U,
- 0x17171717U, 0x2b2b2b2bU, 0x04040404U, 0x7e7e7e7eU,
- 0xbabababaU, 0x77777777U, 0xd6d6d6d6U, 0x26262626U,
- 0xe1e1e1e1U, 0x69696969U, 0x14141414U, 0x63636363U,
- 0x55555555U, 0x21212121U, 0x0c0c0c0cU, 0x7d7d7d7dU,
-};
-static const u32 rcon[] = {
- 0x01000000, 0x02000000, 0x04000000, 0x08000000,
- 0x10000000, 0x20000000, 0x40000000, 0x80000000,
- 0x1B000000, 0x36000000, /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */
-};
-
-/**
- * Expand the cipher key into the encryption key schedule.
- */
-int AES_set_encrypt_key(const unsigned char *userKey, const int bits,
- AES_KEY *key) {
-
- u32 *rk;
- int i = 0;
- u32 temp;
-
- if (!userKey || !key)
- return -1;
- if (bits != 128 && bits != 192 && bits != 256)
- return -2;
-
- rk = key->rd_key;
-
- if (bits==128)
- key->rounds = 10;
- else if (bits==192)
- key->rounds = 12;
- else
- key->rounds = 14;
-
- rk[0] = GETU32(userKey );
- rk[1] = GETU32(userKey + 4);
- rk[2] = GETU32(userKey + 8);
- rk[3] = GETU32(userKey + 12);
- if (bits == 128) {
- while (1) {
- temp = rk[3];
- rk[4] = rk[0] ^
- (Te4[(temp >> 16) & 0xff] & 0xff000000) ^
- (Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^
- (Te4[(temp ) & 0xff] & 0x0000ff00) ^
- (Te4[(temp >> 24) ] & 0x000000ff) ^
- rcon[i];
- rk[5] = rk[1] ^ rk[4];
- rk[6] = rk[2] ^ rk[5];
- rk[7] = rk[3] ^ rk[6];
- if (++i == 10) {
- return 0;
- }
- rk += 4;
- }
- }
- rk[4] = GETU32(userKey + 16);
- rk[5] = GETU32(userKey + 20);
- if (bits == 192) {
- while (1) {
- temp = rk[ 5];
- rk[ 6] = rk[ 0] ^
- (Te4[(temp >> 16) & 0xff] & 0xff000000) ^
- (Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^
- (Te4[(temp ) & 0xff] & 0x0000ff00) ^
- (Te4[(temp >> 24) ] & 0x000000ff) ^
- rcon[i];
- rk[ 7] = rk[ 1] ^ rk[ 6];
- rk[ 8] = rk[ 2] ^ rk[ 7];
- rk[ 9] = rk[ 3] ^ rk[ 8];
- if (++i == 8) {
- return 0;
- }
- rk[10] = rk[ 4] ^ rk[ 9];
- rk[11] = rk[ 5] ^ rk[10];
- rk += 6;
- }
- }
- rk[6] = GETU32(userKey + 24);
- rk[7] = GETU32(userKey + 28);
- if (bits == 256) {
- while (1) {
- temp = rk[ 7];
- rk[ 8] = rk[ 0] ^
- (Te4[(temp >> 16) & 0xff] & 0xff000000) ^
- (Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^
- (Te4[(temp ) & 0xff] & 0x0000ff00) ^
- (Te4[(temp >> 24) ] & 0x000000ff) ^
- rcon[i];
- rk[ 9] = rk[ 1] ^ rk[ 8];
- rk[10] = rk[ 2] ^ rk[ 9];
- rk[11] = rk[ 3] ^ rk[10];
- if (++i == 7) {
- return 0;
- }
- temp = rk[11];
- rk[12] = rk[ 4] ^
- (Te4[(temp >> 24) ] & 0xff000000) ^
- (Te4[(temp >> 16) & 0xff] & 0x00ff0000) ^
- (Te4[(temp >> 8) & 0xff] & 0x0000ff00) ^
- (Te4[(temp ) & 0xff] & 0x000000ff);
- rk[13] = rk[ 5] ^ rk[12];
- rk[14] = rk[ 6] ^ rk[13];
- rk[15] = rk[ 7] ^ rk[14];
-
- rk += 8;
- }
- }
- return 0;
-}
-
-/**
- * Expand the cipher key into the decryption key schedule.
- */
-int AES_set_decrypt_key(const unsigned char *userKey, const int bits,
- AES_KEY *key) {
-
- u32 *rk;
- int i, j, status;
- u32 temp;
-
- /* first, start with an encryption schedule */
- status = AES_set_encrypt_key(userKey, bits, key);
- if (status < 0)
- return status;
-
- rk = key->rd_key;
-
- /* invert the order of the round keys: */
- for (i = 0, j = 4*(key->rounds); i < j; i += 4, j -= 4) {
- temp = rk[i ]; rk[i ] = rk[j ]; rk[j ] = temp;
- temp = rk[i + 1]; rk[i + 1] = rk[j + 1]; rk[j + 1] = temp;
- temp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp;
- temp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp;
- }
- /* apply the inverse MixColumn transform to all round keys but the first and the last: */
- for (i = 1; i < (key->rounds); i++) {
- rk += 4;
- rk[0] =
- Td0[Te4[(rk[0] >> 24) ] & 0xff] ^
- Td1[Te4[(rk[0] >> 16) & 0xff] & 0xff] ^
- Td2[Te4[(rk[0] >> 8) & 0xff] & 0xff] ^
- Td3[Te4[(rk[0] ) & 0xff] & 0xff];
- rk[1] =
- Td0[Te4[(rk[1] >> 24) ] & 0xff] ^
- Td1[Te4[(rk[1] >> 16) & 0xff] & 0xff] ^
- Td2[Te4[(rk[1] >> 8) & 0xff] & 0xff] ^
- Td3[Te4[(rk[1] ) & 0xff] & 0xff];
- rk[2] =
- Td0[Te4[(rk[2] >> 24) ] & 0xff] ^
- Td1[Te4[(rk[2] >> 16) & 0xff] & 0xff] ^
- Td2[Te4[(rk[2] >> 8) & 0xff] & 0xff] ^
- Td3[Te4[(rk[2] ) & 0xff] & 0xff];
- rk[3] =
- Td0[Te4[(rk[3] >> 24) ] & 0xff] ^
- Td1[Te4[(rk[3] >> 16) & 0xff] & 0xff] ^
- Td2[Te4[(rk[3] >> 8) & 0xff] & 0xff] ^
- Td3[Te4[(rk[3] ) & 0xff] & 0xff];
- }
- return 0;
-}
-
-#ifndef AES_ASM
-/*
- * Encrypt a single block
- * in and out can overlap
- */
-void AES_encrypt(const unsigned char *in, unsigned char *out,
- const AES_KEY *key) {
-
- const u32 *rk;
- u32 s0, s1, s2, s3, t0, t1, t2, t3;
-#ifndef FULL_UNROLL
- int r;
-#endif /* ?FULL_UNROLL */
-
- assert(in && out && key);
- rk = key->rd_key;
-
- /*
- * map byte array block to cipher state
- * and add initial round key:
- */
- s0 = GETU32(in ) ^ rk[0];
- s1 = GETU32(in + 4) ^ rk[1];
- s2 = GETU32(in + 8) ^ rk[2];
- s3 = GETU32(in + 12) ^ rk[3];
-#ifdef FULL_UNROLL
- /* round 1: */
- t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[ 4];
- t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[ 5];
- t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[ 6];
- t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[ 7];
- /* round 2: */
- s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[ 8];
- s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[ 9];
- s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[10];
- s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[11];
- /* round 3: */
- t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[12];
- t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[13];
- t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[14];
- t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[15];
- /* round 4: */
- s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[16];
- s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[17];
- s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[18];
- s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[19];
- /* round 5: */
- t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[20];
- t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[21];
- t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[22];
- t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[23];
- /* round 6: */
- s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[24];
- s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[25];
- s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[26];
- s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[27];
- /* round 7: */
- t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[28];
- t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[29];
- t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[30];
- t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[31];
- /* round 8: */
- s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[32];
- s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[33];
- s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[34];
- s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[35];
- /* round 9: */
- t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[36];
- t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[37];
- t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[38];
- t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[39];
- if (key->rounds > 10) {
- /* round 10: */
- s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[40];
- s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[41];
- s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[42];
- s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[43];
- /* round 11: */
- t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[44];
- t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[45];
- t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[46];
- t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[47];
- if (key->rounds > 12) {
- /* round 12: */
- s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[48];
- s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[49];
- s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[50];
- s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[51];
- /* round 13: */
- t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[52];
- t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[53];
- t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[54];
- t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[55];
- }
- }
- rk += key->rounds << 2;
-#else /* !FULL_UNROLL */
- /*
- * Nr - 1 full rounds:
- */
- r = key->rounds >> 1;
- for (;;) {
- t0 =
- Te0[(s0 >> 24) ] ^
- Te1[(s1 >> 16) & 0xff] ^
- Te2[(s2 >> 8) & 0xff] ^
- Te3[(s3 ) & 0xff] ^
- rk[4];
- t1 =
- Te0[(s1 >> 24) ] ^
- Te1[(s2 >> 16) & 0xff] ^
- Te2[(s3 >> 8) & 0xff] ^
- Te3[(s0 ) & 0xff] ^
- rk[5];
- t2 =
- Te0[(s2 >> 24) ] ^
- Te1[(s3 >> 16) & 0xff] ^
- Te2[(s0 >> 8) & 0xff] ^
- Te3[(s1 ) & 0xff] ^
- rk[6];
- t3 =
- Te0[(s3 >> 24) ] ^
- Te1[(s0 >> 16) & 0xff] ^
- Te2[(s1 >> 8) & 0xff] ^
- Te3[(s2 ) & 0xff] ^
- rk[7];
-
- rk += 8;
- if (--r == 0) {
- break;
- }
-
- s0 =
- Te0[(t0 >> 24) ] ^
- Te1[(t1 >> 16) & 0xff] ^
- Te2[(t2 >> 8) & 0xff] ^
- Te3[(t3 ) & 0xff] ^
- rk[0];
- s1 =
- Te0[(t1 >> 24) ] ^
- Te1[(t2 >> 16) & 0xff] ^
- Te2[(t3 >> 8) & 0xff] ^
- Te3[(t0 ) & 0xff] ^
- rk[1];
- s2 =
- Te0[(t2 >> 24) ] ^
- Te1[(t3 >> 16) & 0xff] ^
- Te2[(t0 >> 8) & 0xff] ^
- Te3[(t1 ) & 0xff] ^
- rk[2];
- s3 =
- Te0[(t3 >> 24) ] ^
- Te1[(t0 >> 16) & 0xff] ^
- Te2[(t1 >> 8) & 0xff] ^
- Te3[(t2 ) & 0xff] ^
- rk[3];
- }
-#endif /* ?FULL_UNROLL */
- /*
- * apply last round and
- * map cipher state to byte array block:
- */
- s0 =
- (Te4[(t0 >> 24) ] & 0xff000000) ^
- (Te4[(t1 >> 16) & 0xff] & 0x00ff0000) ^
- (Te4[(t2 >> 8) & 0xff] & 0x0000ff00) ^
- (Te4[(t3 ) & 0xff] & 0x000000ff) ^
- rk[0];
- PUTU32(out , s0);
- s1 =
- (Te4[(t1 >> 24) ] & 0xff000000) ^
- (Te4[(t2 >> 16) & 0xff] & 0x00ff0000) ^
- (Te4[(t3 >> 8) & 0xff] & 0x0000ff00) ^
- (Te4[(t0 ) & 0xff] & 0x000000ff) ^
- rk[1];
- PUTU32(out + 4, s1);
- s2 =
- (Te4[(t2 >> 24) ] & 0xff000000) ^
- (Te4[(t3 >> 16) & 0xff] & 0x00ff0000) ^
- (Te4[(t0 >> 8) & 0xff] & 0x0000ff00) ^
- (Te4[(t1 ) & 0xff] & 0x000000ff) ^
- rk[2];
- PUTU32(out + 8, s2);
- s3 =
- (Te4[(t3 >> 24) ] & 0xff000000) ^
- (Te4[(t0 >> 16) & 0xff] & 0x00ff0000) ^
- (Te4[(t1 >> 8) & 0xff] & 0x0000ff00) ^
- (Te4[(t2 ) & 0xff] & 0x000000ff) ^
- rk[3];
- PUTU32(out + 12, s3);
-}
-
-/*
- * Decrypt a single block
- * in and out can overlap
- */
-void AES_decrypt(const unsigned char *in, unsigned char *out,
- const AES_KEY *key) {
-
- const u32 *rk;
- u32 s0, s1, s2, s3, t0, t1, t2, t3;
-#ifndef FULL_UNROLL
- int r;
-#endif /* ?FULL_UNROLL */
-
- assert(in && out && key);
- rk = key->rd_key;
-
- /*
- * map byte array block to cipher state
- * and add initial round key:
- */
- s0 = GETU32(in ) ^ rk[0];
- s1 = GETU32(in + 4) ^ rk[1];
- s2 = GETU32(in + 8) ^ rk[2];
- s3 = GETU32(in + 12) ^ rk[3];
-#ifdef FULL_UNROLL
- /* round 1: */
- t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[ 4];
- t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[ 5];
- t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[ 6];
- t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[ 7];
- /* round 2: */
- s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[ 8];
- s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[ 9];
- s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[10];
- s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[11];
- /* round 3: */
- t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[12];
- t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[13];
- t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[14];
- t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[15];
- /* round 4: */
- s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[16];
- s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[17];
- s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[18];
- s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[19];
- /* round 5: */
- t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[20];
- t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[21];
- t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[22];
- t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[23];
- /* round 6: */
- s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[24];
- s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[25];
- s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[26];
- s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[27];
- /* round 7: */
- t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[28];
- t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[29];
- t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[30];
- t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[31];
- /* round 8: */
- s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[32];
- s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[33];
- s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[34];
- s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[35];
- /* round 9: */
- t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[36];
- t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[37];
- t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[38];
- t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[39];
- if (key->rounds > 10) {
- /* round 10: */
- s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[40];
- s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[41];
- s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[42];
- s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[43];
- /* round 11: */
- t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[44];
- t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[45];
- t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[46];
- t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[47];
- if (key->rounds > 12) {
- /* round 12: */
- s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[48];
- s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[49];
- s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[50];
- s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[51];
- /* round 13: */
- t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[52];
- t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[53];
- t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[54];
- t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[55];
- }
- }
- rk += key->rounds << 2;
-#else /* !FULL_UNROLL */
- /*
- * Nr - 1 full rounds:
- */
- r = key->rounds >> 1;
- for (;;) {
- t0 =
- Td0[(s0 >> 24) ] ^
- Td1[(s3 >> 16) & 0xff] ^
- Td2[(s2 >> 8) & 0xff] ^
- Td3[(s1 ) & 0xff] ^
- rk[4];
- t1 =
- Td0[(s1 >> 24) ] ^
- Td1[(s0 >> 16) & 0xff] ^
- Td2[(s3 >> 8) & 0xff] ^
- Td3[(s2 ) & 0xff] ^
- rk[5];
- t2 =
- Td0[(s2 >> 24) ] ^
- Td1[(s1 >> 16) & 0xff] ^
- Td2[(s0 >> 8) & 0xff] ^
- Td3[(s3 ) & 0xff] ^
- rk[6];
- t3 =
- Td0[(s3 >> 24) ] ^
- Td1[(s2 >> 16) & 0xff] ^
- Td2[(s1 >> 8) & 0xff] ^
- Td3[(s0 ) & 0xff] ^
- rk[7];
-
- rk += 8;
- if (--r == 0) {
- break;
- }
-
- s0 =
- Td0[(t0 >> 24) ] ^
- Td1[(t3 >> 16) & 0xff] ^
- Td2[(t2 >> 8) & 0xff] ^
- Td3[(t1 ) & 0xff] ^
- rk[0];
- s1 =
- Td0[(t1 >> 24) ] ^
- Td1[(t0 >> 16) & 0xff] ^
- Td2[(t3 >> 8) & 0xff] ^
- Td3[(t2 ) & 0xff] ^
- rk[1];
- s2 =
- Td0[(t2 >> 24) ] ^
- Td1[(t1 >> 16) & 0xff] ^
- Td2[(t0 >> 8) & 0xff] ^
- Td3[(t3 ) & 0xff] ^
- rk[2];
- s3 =
- Td0[(t3 >> 24) ] ^
- Td1[(t2 >> 16) & 0xff] ^
- Td2[(t1 >> 8) & 0xff] ^
- Td3[(t0 ) & 0xff] ^
- rk[3];
- }
-#endif /* ?FULL_UNROLL */
- /*
- * apply last round and
- * map cipher state to byte array block:
- */
- s0 =
- (Td4[(t0 >> 24) ] & 0xff000000) ^
- (Td4[(t3 >> 16) & 0xff] & 0x00ff0000) ^
- (Td4[(t2 >> 8) & 0xff] & 0x0000ff00) ^
- (Td4[(t1 ) & 0xff] & 0x000000ff) ^
- rk[0];
- PUTU32(out , s0);
- s1 =
- (Td4[(t1 >> 24) ] & 0xff000000) ^
- (Td4[(t0 >> 16) & 0xff] & 0x00ff0000) ^
- (Td4[(t3 >> 8) & 0xff] & 0x0000ff00) ^
- (Td4[(t2 ) & 0xff] & 0x000000ff) ^
- rk[1];
- PUTU32(out + 4, s1);
- s2 =
- (Td4[(t2 >> 24) ] & 0xff000000) ^
- (Td4[(t1 >> 16) & 0xff] & 0x00ff0000) ^
- (Td4[(t0 >> 8) & 0xff] & 0x0000ff00) ^
- (Td4[(t3 ) & 0xff] & 0x000000ff) ^
- rk[2];
- PUTU32(out + 8, s2);
- s3 =
- (Td4[(t3 >> 24) ] & 0xff000000) ^
- (Td4[(t2 >> 16) & 0xff] & 0x00ff0000) ^
- (Td4[(t1 >> 8) & 0xff] & 0x0000ff00) ^
- (Td4[(t0 ) & 0xff] & 0x000000ff) ^
- rk[3];
- PUTU32(out + 12, s3);
-}
-
-#endif /* AES_ASM */
-
-void AES_cbc_encrypt(const unsigned char *in, unsigned char *out,
- const unsigned long length, const AES_KEY *key,
- unsigned char *ivec, const int enc)
-{
-
- unsigned long n;
- unsigned long len = length;
- unsigned char tmp[AES_BLOCK_SIZE];
-
- assert(in && out && key && ivec);
-
- if (enc) {
- while (len >= AES_BLOCK_SIZE) {
- for(n=0; n < AES_BLOCK_SIZE; ++n)
- tmp[n] = in[n] ^ ivec[n];
- AES_encrypt(tmp, out, key);
- memcpy(ivec, out, AES_BLOCK_SIZE);
- len -= AES_BLOCK_SIZE;
- in += AES_BLOCK_SIZE;
- out += AES_BLOCK_SIZE;
- }
- if (len) {
- for(n=0; n < len; ++n)
- tmp[n] = in[n] ^ ivec[n];
- for(n=len; n < AES_BLOCK_SIZE; ++n)
- tmp[n] = ivec[n];
- AES_encrypt(tmp, tmp, key);
- memcpy(out, tmp, AES_BLOCK_SIZE);
- memcpy(ivec, tmp, AES_BLOCK_SIZE);
- }
- } else {
- while (len >= AES_BLOCK_SIZE) {
- memcpy(tmp, in, AES_BLOCK_SIZE);
- AES_decrypt(in, out, key);
- for(n=0; n < AES_BLOCK_SIZE; ++n)
- out[n] ^= ivec[n];
- memcpy(ivec, tmp, AES_BLOCK_SIZE);
- len -= AES_BLOCK_SIZE;
- in += AES_BLOCK_SIZE;
- out += AES_BLOCK_SIZE;
- }
- if (len) {
- memcpy(tmp, in, AES_BLOCK_SIZE);
- AES_decrypt(tmp, tmp, key);
- for(n=0; n < len; ++n)
- out[n] = tmp[n] ^ ivec[n];
- memcpy(ivec, tmp, AES_BLOCK_SIZE);
- }
- }
-}
+++ /dev/null
-#ifndef QEMU_AES_H
-#define QEMU_AES_H
-
-#define AES_MAXNR 14
-#define AES_BLOCK_SIZE 16
-
-struct aes_key_st {
- uint32_t rd_key[4 *(AES_MAXNR + 1)];
- int rounds;
-};
-typedef struct aes_key_st AES_KEY;
-
-int AES_set_encrypt_key(const unsigned char *userKey, const int bits,
- AES_KEY *key);
-int AES_set_decrypt_key(const unsigned char *userKey, const int bits,
- AES_KEY *key);
-
-void AES_encrypt(const unsigned char *in, unsigned char *out,
- const AES_KEY *key);
-void AES_decrypt(const unsigned char *in, unsigned char *out,
- const AES_KEY *key);
-void AES_cbc_encrypt(const unsigned char *in, unsigned char *out,
- const unsigned long length, const AES_KEY *key,
- unsigned char *ivec, const int enc);
-
-#endif
+++ /dev/null
-/*
- * QEMU Audio subsystem
- *
- * Copyright (c) 2003-2004 Vassili Karpov (malc)
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include <assert.h>
-#include "vl.h"
-
-#define USE_WAV_AUDIO
-
-#include "audio/audio_int.h"
-
-#define dolog(...) AUD_log ("audio", __VA_ARGS__)
-#ifdef DEBUG
-#define ldebug(...) dolog (__VA_ARGS__)
-#else
-#define ldebug(...)
-#endif
-
-#define QC_AUDIO_DRV "QEMU_AUDIO_DRV"
-#define QC_VOICES "QEMU_VOICES"
-#define QC_FIXED_FORMAT "QEMU_FIXED_FORMAT"
-#define QC_FIXED_FREQ "QEMU_FIXED_FREQ"
-
-static HWVoice *hw_voices;
-
-AudioState audio_state = {
- 1, /* use fixed settings */
- 44100, /* fixed frequency */
- 2, /* fixed channels */
- AUD_FMT_S16, /* fixed format */
- 1, /* number of hw voices */
- -1 /* voice size */
-};
-
-/* http://www.df.lth.se/~john_e/gems/gem002d.html */
-/* http://www.multi-platforms.com/Tips/PopCount.htm */
-uint32_t popcount (uint32_t u)
-{
- u = ((u&0x55555555) + ((u>>1)&0x55555555));
- u = ((u&0x33333333) + ((u>>2)&0x33333333));
- u = ((u&0x0f0f0f0f) + ((u>>4)&0x0f0f0f0f));
- u = ((u&0x00ff00ff) + ((u>>8)&0x00ff00ff));
- u = ( u&0x0000ffff) + (u>>16);
- return u;
-}
-
-inline uint32_t lsbindex (uint32_t u)
-{
- return popcount ((u&-u)-1);
-}
-
-int audio_get_conf_int (const char *key, int defval)
-{
- int val = defval;
- char *strval;
-
- strval = getenv (key);
- if (strval) {
- val = atoi (strval);
- }
-
- return val;
-}
-
-const char *audio_get_conf_str (const char *key, const char *defval)
-{
- const char *val = getenv (key);
- if (!val)
- return defval;
- else
- return val;
-}
-
-void AUD_log (const char *cap, const char *fmt, ...)
-{
- va_list ap;
- fprintf (stderr, "%s: ", cap);
- va_start (ap, fmt);
- vfprintf (stderr, fmt, ap);
- va_end (ap);
-}
-
-/*
- * Soft Voice
- */
-void pcm_sw_free_resources (SWVoice *sw)
-{
- if (sw->buf) qemu_free (sw->buf);
- if (sw->rate) st_rate_stop (sw->rate);
- sw->buf = NULL;
- sw->rate = NULL;
-}
-
-int pcm_sw_alloc_resources (SWVoice *sw)
-{
- sw->buf = qemu_mallocz (sw->hw->samples * sizeof (st_sample_t));
- if (!sw->buf)
- return -1;
-
- sw->rate = st_rate_start (sw->freq, sw->hw->freq);
- if (!sw->rate) {
- qemu_free (sw->buf);
- sw->buf = NULL;
- return -1;
- }
- return 0;
-}
-
-void pcm_sw_fini (SWVoice *sw)
-{
- pcm_sw_free_resources (sw);
-}
-
-int pcm_sw_init (SWVoice *sw, HWVoice *hw, int freq,
- int nchannels, audfmt_e fmt)
-{
- int bits = 8, sign = 0;
-
- switch (fmt) {
- case AUD_FMT_S8:
- sign = 1;
- case AUD_FMT_U8:
- break;
-
- case AUD_FMT_S16:
- sign = 1;
- case AUD_FMT_U16:
- bits = 16;
- break;
- }
-
- sw->hw = hw;
- sw->freq = freq;
- sw->fmt = fmt;
- sw->nchannels = nchannels;
- sw->shift = (nchannels == 2) + (bits == 16);
- sw->align = (1 << sw->shift) - 1;
- sw->left = 0;
- sw->pos = 0;
- sw->wpos = 0;
- sw->live = 0;
- sw->ratio = (sw->hw->freq * ((int64_t) INT_MAX)) / sw->freq;
- sw->bytes_per_second = sw->freq << sw->shift;
- sw->conv = mixeng_conv[nchannels == 2][sign][bits == 16];
-
- pcm_sw_free_resources (sw);
- return pcm_sw_alloc_resources (sw);
-}
-
-/* Hard voice */
-void pcm_hw_free_resources (HWVoice *hw)
-{
- if (hw->mix_buf)
- qemu_free (hw->mix_buf);
- hw->mix_buf = NULL;
-}
-
-int pcm_hw_alloc_resources (HWVoice *hw)
-{
- hw->mix_buf = qemu_mallocz (hw->samples * sizeof (st_sample_t));
- if (!hw->mix_buf)
- return -1;
- return 0;
-}
-
-void pcm_hw_fini (HWVoice *hw)
-{
- if (hw->active) {
- ldebug ("pcm_hw_fini: %d %d %d\n", hw->freq, hw->nchannels, hw->fmt);
- pcm_hw_free_resources (hw);
- hw->pcm_ops->fini (hw);
- memset (hw, 0, audio_state.drv->voice_size);
- }
-}
-
-void pcm_hw_gc (HWVoice *hw)
-{
- if (hw->nb_voices)
- return;
-
- pcm_hw_fini (hw);
-}
-
-int pcm_hw_get_live (HWVoice *hw)
-{
- int i, alive = 0, live = hw->samples;
-
- for (i = 0; i < hw->nb_voices; i++) {
- if (hw->pvoice[i]->live) {
- live = audio_MIN (hw->pvoice[i]->live, live);
- alive += 1;
- }
- }
-
- if (alive)
- return live;
- else
- return -1;
-}
-
-int pcm_hw_get_live2 (HWVoice *hw, int *nb_active)
-{
- int i, alive = 0, live = hw->samples;
-
- *nb_active = 0;
- for (i = 0; i < hw->nb_voices; i++) {
- if (hw->pvoice[i]->live) {
- if (hw->pvoice[i]->live < live) {
- *nb_active = hw->pvoice[i]->active != 0;
- live = hw->pvoice[i]->live;
- }
- alive += 1;
- }
- }
-
- if (alive)
- return live;
- else
- return -1;
-}
-
-void pcm_hw_dec_live (HWVoice *hw, int decr)
-{
- int i;
-
- for (i = 0; i < hw->nb_voices; i++) {
- if (hw->pvoice[i]->live) {
- hw->pvoice[i]->live -= decr;
- }
- }
-}
-
-void pcm_hw_clear (HWVoice *hw, void *buf, int len)
-{
- if (!len)
- return;
-
- switch (hw->fmt) {
- case AUD_FMT_S16:
- case AUD_FMT_S8:
- memset (buf, 0x00, len << hw->shift);
- break;
-
- case AUD_FMT_U8:
- memset (buf, 0x80, len << hw->shift);
- break;
-
- case AUD_FMT_U16:
- {
- unsigned int i;
- uint16_t *p = buf;
- int shift = hw->nchannels - 1;
-
- for (i = 0; i < len << shift; i++) {
- p[i] = INT16_MAX;
- }
- }
- break;
- }
-}
-
-int pcm_hw_write (SWVoice *sw, void *buf, int size)
-{
- int hwsamples, samples, isamp, osamp, wpos, live, dead, left, swlim, blck;
- int ret = 0, pos = 0;
- if (!sw)
- return size;
-
- hwsamples = sw->hw->samples;
- samples = size >> sw->shift;
-
- if (!sw->live) {
- sw->wpos = sw->hw->rpos;
- }
- wpos = sw->wpos;
- live = sw->live;
- dead = hwsamples - live;
- swlim = (dead * ((int64_t) INT_MAX)) / sw->ratio;
- swlim = audio_MIN (swlim, samples);
-
- ldebug ("size=%d live=%d dead=%d swlim=%d wpos=%d\n",
- size, live, dead, swlim, wpos);
- if (swlim)
- sw->conv (sw->buf, buf, swlim);
-
- while (swlim) {
- dead = hwsamples - live;
- left = hwsamples - wpos;
- blck = audio_MIN (dead, left);
- if (!blck) {
- /* dolog ("swlim=%d\n", swlim); */
- break;
- }
- isamp = swlim;
- osamp = blck;
- st_rate_flow (sw->rate, sw->buf + pos, sw->hw->mix_buf + wpos, &isamp, &osamp);
- ret += isamp;
- swlim -= isamp;
- pos += isamp;
- live += osamp;
- wpos = (wpos + osamp) % hwsamples;
- }
-
- sw->wpos = wpos;
- sw->live = live;
- return ret << sw->shift;
-}
-
-int pcm_hw_init (HWVoice *hw, int freq, int nchannels, audfmt_e fmt)
-{
- int sign = 0, bits = 8;
-
- pcm_hw_fini (hw);
- ldebug ("pcm_hw_init: %d %d %d\n", freq, nchannels, fmt);
- if (hw->pcm_ops->init (hw, freq, nchannels, fmt)) {
- memset (hw, 0, audio_state.drv->voice_size);
- return -1;
- }
-
- switch (hw->fmt) {
- case AUD_FMT_S8:
- sign = 1;
- case AUD_FMT_U8:
- break;
-
- case AUD_FMT_S16:
- sign = 1;
- case AUD_FMT_U16:
- bits = 16;
- break;
- }
-
- hw->nb_voices = 0;
- hw->active = 1;
- hw->shift = (hw->nchannels == 2) + (bits == 16);
- hw->bytes_per_second = hw->freq << hw->shift;
- hw->align = (1 << hw->shift) - 1;
- hw->samples = hw->bufsize >> hw->shift;
- hw->clip = mixeng_clip[hw->nchannels == 2][sign][bits == 16];
- if (pcm_hw_alloc_resources (hw)) {
- pcm_hw_fini (hw);
- return -1;
- }
- return 0;
-}
-
-static int dist (void *hw)
-{
- if (hw) {
- return (((uint8_t *) hw - (uint8_t *) hw_voices)
- / audio_state.voice_size) + 1;
- }
- else {
- return 0;
- }
-}
-
-#define ADVANCE(hw) hw ? advance (hw, audio_state.voice_size) : hw_voices
-
-HWVoice *pcm_hw_find_any (HWVoice *hw)
-{
- int i = dist (hw);
- for (; i < audio_state.nb_hw_voices; i++) {
- hw = ADVANCE (hw);
- return hw;
- }
- return NULL;
-}
-
-HWVoice *pcm_hw_find_any_active (HWVoice *hw)
-{
- int i = dist (hw);
- for (; i < audio_state.nb_hw_voices; i++) {
- hw = ADVANCE (hw);
- if (hw->active)
- return hw;
- }
- return NULL;
-}
-
-HWVoice *pcm_hw_find_any_active_enabled (HWVoice *hw)
-{
- int i = dist (hw);
- for (; i < audio_state.nb_hw_voices; i++) {
- hw = ADVANCE (hw);
- if (hw->active && hw->enabled)
- return hw;
- }
- return NULL;
-}
-
-HWVoice *pcm_hw_find_any_passive (HWVoice *hw)
-{
- int i = dist (hw);
- for (; i < audio_state.nb_hw_voices; i++) {
- hw = ADVANCE (hw);
- if (!hw->active)
- return hw;
- }
- return NULL;
-}
-
-HWVoice *pcm_hw_find_specific (HWVoice *hw, int freq,
- int nchannels, audfmt_e fmt)
-{
- while ((hw = pcm_hw_find_any_active (hw))) {
- if (hw->freq == freq &&
- hw->nchannels == nchannels &&
- hw->fmt == fmt)
- return hw;
- }
- return NULL;
-}
-
-HWVoice *pcm_hw_add (int freq, int nchannels, audfmt_e fmt)
-{
- HWVoice *hw;
-
- if (audio_state.fixed_format) {
- freq = audio_state.fixed_freq;
- nchannels = audio_state.fixed_channels;
- fmt = audio_state.fixed_fmt;
- }
-
- hw = pcm_hw_find_specific (NULL, freq, nchannels, fmt);
-
- if (hw)
- return hw;
-
- hw = pcm_hw_find_any_passive (NULL);
- if (hw) {
- hw->pcm_ops = audio_state.drv->pcm_ops;
- if (!hw->pcm_ops)
- return NULL;
-
- if (pcm_hw_init (hw, freq, nchannels, fmt)) {
- pcm_hw_gc (hw);
- return NULL;
- }
- else
- return hw;
- }
-
- return pcm_hw_find_any (NULL);
-}
-
-int pcm_hw_add_sw (HWVoice *hw, SWVoice *sw)
-{
- SWVoice **pvoice = qemu_mallocz ((hw->nb_voices + 1) * sizeof (sw));
- if (!pvoice)
- return -1;
-
- memcpy (pvoice, hw->pvoice, hw->nb_voices * sizeof (sw));
- qemu_free (hw->pvoice);
- hw->pvoice = pvoice;
- hw->pvoice[hw->nb_voices++] = sw;
- return 0;
-}
-
-int pcm_hw_del_sw (HWVoice *hw, SWVoice *sw)
-{
- int i, j;
- if (hw->nb_voices > 1) {
- SWVoice **pvoice = qemu_mallocz ((hw->nb_voices - 1) * sizeof (sw));
-
- if (!pvoice) {
- dolog ("Can not maintain consistent state (not enough memory)\n");
- return -1;
- }
-
- for (i = 0, j = 0; i < hw->nb_voices; i++) {
- if (j >= hw->nb_voices - 1) {
- dolog ("Can not maintain consistent state "
- "(invariant violated)\n");
- return -1;
- }
- if (hw->pvoice[i] != sw)
- pvoice[j++] = hw->pvoice[i];
- }
- qemu_free (hw->pvoice);
- hw->pvoice = pvoice;
- hw->nb_voices -= 1;
- }
- else {
- qemu_free (hw->pvoice);
- hw->pvoice = NULL;
- hw->nb_voices = 0;
- }
- return 0;
-}
-
-SWVoice *pcm_create_voice_pair (int freq, int nchannels, audfmt_e fmt)
-{
- SWVoice *sw;
- HWVoice *hw;
-
- sw = qemu_mallocz (sizeof (*sw));
- if (!sw)
- goto err1;
-
- hw = pcm_hw_add (freq, nchannels, fmt);
- if (!hw)
- goto err2;
-
- if (pcm_hw_add_sw (hw, sw))
- goto err3;
-
- if (pcm_sw_init (sw, hw, freq, nchannels, fmt))
- goto err4;
-
- return sw;
-
-err4:
- pcm_hw_del_sw (hw, sw);
-err3:
- pcm_hw_gc (hw);
-err2:
- qemu_free (sw);
-err1:
- return NULL;
-}
-
-SWVoice *AUD_open (SWVoice *sw, const char *name,
- int freq, int nchannels, audfmt_e fmt)
-{
- if (!audio_state.drv) {
- return NULL;
- }
-
- if (sw && freq == sw->freq && sw->nchannels == nchannels && sw->fmt == fmt) {
- return sw;
- }
-
- if (sw) {
- ldebug ("Different format %s %d %d %d\n",
- name,
- sw->freq == freq,
- sw->nchannels == nchannels,
- sw->fmt == fmt);
- }
-
- if (nchannels != 1 && nchannels != 2) {
- dolog ("Bogus channel count %d for voice %s\n", nchannels, name);
- return NULL;
- }
-
- if (!audio_state.fixed_format && sw) {
- pcm_sw_fini (sw);
- pcm_hw_del_sw (sw->hw, sw);
- pcm_hw_gc (sw->hw);
- if (sw->name) {
- qemu_free (sw->name);
- sw->name = NULL;
- }
- qemu_free (sw);
- sw = NULL;
- }
-
- if (sw) {
- HWVoice *hw = sw->hw;
- if (!hw) {
- dolog ("Internal logic error voice %s has no hardware store\n",
- name);
- return sw;
- }
-
- if (pcm_sw_init (sw, hw, freq, nchannels, fmt)) {
- pcm_sw_fini (sw);
- pcm_hw_del_sw (hw, sw);
- pcm_hw_gc (hw);
- if (sw->name) {
- qemu_free (sw->name);
- sw->name = NULL;
- }
- qemu_free (sw);
- return NULL;
- }
- }
- else {
- sw = pcm_create_voice_pair (freq, nchannels, fmt);
- if (!sw) {
- dolog ("Failed to create voice %s\n", name);
- return NULL;
- }
- }
-
- if (sw->name) {
- qemu_free (sw->name);
- sw->name = NULL;
- }
- sw->name = qemu_strdup (name);
- return sw;
-}
-
-void AUD_close (SWVoice *sw)
-{
- if (!sw)
- return;
-
- pcm_sw_fini (sw);
- pcm_hw_del_sw (sw->hw, sw);
- pcm_hw_gc (sw->hw);
- if (sw->name) {
- qemu_free (sw->name);
- sw->name = NULL;
- }
- qemu_free (sw);
-}
-
-int AUD_write (SWVoice *sw, void *buf, int size)
-{
- int bytes;
-
- if (!sw->hw->enabled)
- dolog ("Writing to disabled voice %s\n", sw->name);
- bytes = sw->hw->pcm_ops->write (sw, buf, size);
- return bytes;
-}
-
-void AUD_run (void)
-{
- HWVoice *hw = NULL;
-
- while ((hw = pcm_hw_find_any_active_enabled (hw))) {
- int i;
- if (hw->pending_disable && pcm_hw_get_live (hw) <= 0) {
- hw->enabled = 0;
- hw->pcm_ops->ctl (hw, VOICE_DISABLE);
- for (i = 0; i < hw->nb_voices; i++) {
- hw->pvoice[i]->live = 0;
- /* hw->pvoice[i]->old_ticks = 0; */
- }
- continue;
- }
-
- hw->pcm_ops->run (hw);
- assert (hw->rpos < hw->samples);
- for (i = 0; i < hw->nb_voices; i++) {
- SWVoice *sw = hw->pvoice[i];
- if (!sw->active && !sw->live && sw->old_ticks) {
- int64_t delta = qemu_get_clock (vm_clock) - sw->old_ticks;
- if (delta > audio_state.ticks_threshold) {
- ldebug ("resetting old_ticks for %s\n", sw->name);
- sw->old_ticks = 0;
- }
- }
- }
- }
-}
-
-int AUD_get_free (SWVoice *sw)
-{
- int free;
-
- if (!sw)
- return 4096;
-
- free = ((sw->hw->samples - sw->live) << sw->hw->shift) * sw->ratio
- / INT_MAX;
-
- free &= ~sw->hw->align;
- if (!free) return 0;
-
- return free;
-}
-
-int AUD_get_buffer_size (SWVoice *sw)
-{
- return sw->hw->bufsize;
-}
-
-void AUD_adjust (SWVoice *sw, int bytes)
-{
- if (!sw)
- return;
- sw->old_ticks += (ticks_per_sec * (int64_t) bytes) / sw->bytes_per_second;
-}
-
-void AUD_reset (SWVoice *sw)
-{
- sw->active = 0;
- sw->old_ticks = 0;
-}
-
-int AUD_calc_elapsed (SWVoice *sw)
-{
- int64_t now, delta, bytes;
- int dead, swlim;
-
- if (!sw)
- return 0;
-
- now = qemu_get_clock (vm_clock);
- delta = now - sw->old_ticks;
- bytes = (delta * sw->bytes_per_second) / ticks_per_sec;
- if (delta < 0) {
- dolog ("whoops delta(<0)=%"PRId64"\n", delta);
- return 0;
- }
-
- dead = sw->hw->samples - sw->live;
- swlim = ((dead * (int64_t) INT_MAX) / sw->ratio);
-
- if (bytes > swlim) {
- return swlim;
- }
- else {
- return bytes;
- }
-}
-
-void AUD_enable (SWVoice *sw, int on)
-{
- int i;
- HWVoice *hw;
-
- if (!sw)
- return;
-
- hw = sw->hw;
- if (on) {
- if (!sw->live)
- sw->wpos = sw->hw->rpos;
- if (!sw->old_ticks) {
- sw->old_ticks = qemu_get_clock (vm_clock);
- }
- }
-
- if (sw->active != on) {
- if (on) {
- hw->pending_disable = 0;
- if (!hw->enabled) {
- hw->enabled = 1;
- for (i = 0; i < hw->nb_voices; i++) {
- ldebug ("resetting voice\n");
- sw = hw->pvoice[i];
- sw->old_ticks = qemu_get_clock (vm_clock);
- }
- hw->pcm_ops->ctl (hw, VOICE_ENABLE);
- }
- }
- else {
- if (hw->enabled && !hw->pending_disable) {
- int nb_active = 0;
- for (i = 0; i < hw->nb_voices; i++) {
- nb_active += hw->pvoice[i]->active != 0;
- }
-
- if (nb_active == 1) {
- hw->pending_disable = 1;
- }
- }
- }
- sw->active = on;
- }
-}
-
-static struct audio_output_driver *drvtab[] = {
-#ifdef CONFIG_OSS
- &oss_output_driver,
-#endif
-#ifdef CONFIG_FMOD
- &fmod_output_driver,
-#endif
-#ifdef CONFIG_SDL
- &sdl_output_driver,
-#endif
- &no_output_driver,
-#ifdef USE_WAV_AUDIO
- &wav_output_driver,
-#endif
-};
-
-static int voice_init (struct audio_output_driver *drv)
-{
- audio_state.opaque = drv->init ();
- if (audio_state.opaque) {
- if (audio_state.nb_hw_voices > drv->max_voices) {
- dolog ("`%s' does not support %d multiple hardware channels\n"
- "Resetting to %d\n",
- drv->name, audio_state.nb_hw_voices, drv->max_voices);
- audio_state.nb_hw_voices = drv->max_voices;
- }
- hw_voices = qemu_mallocz (audio_state.nb_hw_voices * drv->voice_size);
- if (hw_voices) {
- audio_state.drv = drv;
- return 1;
- }
- else {
- dolog ("Not enough memory for %d `%s' voices (each %d bytes)\n",
- audio_state.nb_hw_voices, drv->name, drv->voice_size);
- drv->fini (audio_state.opaque);
- return 0;
- }
- }
- else {
- dolog ("Could not init `%s' audio\n", drv->name);
- return 0;
- }
-}
-
-static void audio_vm_stop_handler (void *opaque, int reason)
-{
- HWVoice *hw = NULL;
-
- while ((hw = pcm_hw_find_any (hw))) {
- if (!hw->pcm_ops)
- continue;
-
- hw->pcm_ops->ctl (hw, reason ? VOICE_ENABLE : VOICE_DISABLE);
- }
-}
-
-static void audio_atexit (void)
-{
- HWVoice *hw = NULL;
-
- while ((hw = pcm_hw_find_any (hw))) {
- if (!hw->pcm_ops)
- continue;
-
- hw->pcm_ops->ctl (hw, VOICE_DISABLE);
- hw->pcm_ops->fini (hw);
- }
- audio_state.drv->fini (audio_state.opaque);
-}
-
-static void audio_save (QEMUFile *f, void *opaque)
-{
-}
-
-static int audio_load (QEMUFile *f, void *opaque, int version_id)
-{
- if (version_id != 1)
- return -EINVAL;
-
- return 0;
-}
-
-void AUD_init (void)
-{
- int i;
- int done = 0;
- const char *drvname;
-
- audio_state.fixed_format =
- !!audio_get_conf_int (QC_FIXED_FORMAT, audio_state.fixed_format);
- audio_state.fixed_freq =
- audio_get_conf_int (QC_FIXED_FREQ, audio_state.fixed_freq);
- audio_state.nb_hw_voices =
- audio_get_conf_int (QC_VOICES, audio_state.nb_hw_voices);
-
- if (audio_state.nb_hw_voices <= 0) {
- dolog ("Bogus number of voices %d, resetting to 1\n",
- audio_state.nb_hw_voices);
- }
-
- drvname = audio_get_conf_str (QC_AUDIO_DRV, NULL);
- if (drvname) {
- int found = 0;
- for (i = 0; i < sizeof (drvtab) / sizeof (drvtab[0]); i++) {
- if (!strcmp (drvname, drvtab[i]->name)) {
- done = voice_init (drvtab[i]);
- found = 1;
- break;
- }
- }
- if (!found) {
- dolog ("Unknown audio driver `%s'\n", drvname);
- }
- }
-
- qemu_add_vm_stop_handler (audio_vm_stop_handler, NULL);
- atexit (audio_atexit);
-
- if (!done) {
- for (i = 0; !done && i < sizeof (drvtab) / sizeof (drvtab[0]); i++) {
- if (drvtab[i]->can_be_default)
- done = voice_init (drvtab[i]);
- }
- }
-
- audio_state.ticks_threshold = ticks_per_sec / 50;
- audio_state.freq_threshold = 100;
-
- register_savevm ("audio", 0, 1, audio_save, audio_load, NULL);
- if (!done) {
- dolog ("Can not initialize audio subsystem\n");
- voice_init (&no_output_driver);
- }
-}
+++ /dev/null
-/*
- * QEMU Audio subsystem header
- *
- * Copyright (c) 2003-2004 Vassili Karpov (malc)
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#ifndef QEMU_AUDIO_H
-#define QEMU_AUDIO_H
-
-#include "mixeng.h"
-
-typedef enum {
- AUD_FMT_U8,
- AUD_FMT_S8,
- AUD_FMT_U16,
- AUD_FMT_S16
-} audfmt_e;
-
-typedef struct SWVoice SWVoice;
-
-SWVoice * AUD_open (SWVoice *sw, const char *name, int freq,
- int nchannels, audfmt_e fmt);
-void AUD_init (void);
-void AUD_log (const char *cap, const char *fmt, ...)
- __attribute__ ((__format__ (__printf__, 2, 3)));;
-void AUD_close (SWVoice *sw);
-int AUD_write (SWVoice *sw, void *pcm_buf, int size);
-void AUD_adjust (SWVoice *sw, int leftover);
-void AUD_reset (SWVoice *sw);
-int AUD_get_free (SWVoice *sw);
-int AUD_get_buffer_size (SWVoice *sw);
-void AUD_run (void);
-void AUD_enable (SWVoice *sw, int on);
-int AUD_calc_elapsed (SWVoice *sw);
-
-static inline void *advance (void *p, int incr)
-{
- uint8_t *d = p;
- return (d + incr);
-}
-
-uint32_t popcount (uint32_t u);
-inline uint32_t lsbindex (uint32_t u);
-
-#define audio_MIN(a, b) ((a)>(b)?(b):(a))
-#define audio_MAX(a, b) ((a)<(b)?(b):(a))
-
-#endif /* audio.h */
+++ /dev/null
-/*
- * QEMU Audio subsystem header
- *
- * Copyright (c) 2003-2004 Vassili Karpov (malc)
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#ifndef QEMU_AUDIO_INT_H
-#define QEMU_AUDIO_INT_H
-
-#include "vl.h"
-
-struct pcm_ops;
-
-typedef struct HWVoice {
- int active;
- int enabled;
- int pending_disable;
- int valid;
- int freq;
-
- f_sample *clip;
- audfmt_e fmt;
- int nchannels;
-
- int align;
- int shift;
-
- int rpos;
- int bufsize;
-
- int bytes_per_second;
- st_sample_t *mix_buf;
-
- int samples;
- int64_t old_ticks;
- int nb_voices;
- struct SWVoice **pvoice;
- struct pcm_ops *pcm_ops;
-} HWVoice;
-
-extern struct pcm_ops no_pcm_ops;
-extern struct audio_output_driver no_output_driver;
-
-extern struct pcm_ops oss_pcm_ops;
-extern struct audio_output_driver oss_output_driver;
-
-extern struct pcm_ops sdl_pcm_ops;
-extern struct audio_output_driver sdl_output_driver;
-
-extern struct pcm_ops wav_pcm_ops;
-extern struct audio_output_driver wav_output_driver;
-
-extern struct pcm_ops fmod_pcm_ops;
-extern struct audio_output_driver fmod_output_driver;
-
-struct audio_output_driver {
- const char *name;
- void *(*init) (void);
- void (*fini) (void *);
- struct pcm_ops *pcm_ops;
- int can_be_default;
- int max_voices;
- int voice_size;
-};
-
-typedef struct AudioState {
- int fixed_format;
- int fixed_freq;
- int fixed_channels;
- int fixed_fmt;
- int nb_hw_voices;
- int voice_size;
- int64_t ticks_threshold;
- int freq_threshold;
- void *opaque;
- struct audio_output_driver *drv;
-} AudioState;
-extern AudioState audio_state;
-
-struct SWVoice {
- int freq;
- audfmt_e fmt;
- int nchannels;
-
- int shift;
- int align;
-
- t_sample *conv;
-
- int left;
- int pos;
- int bytes_per_second;
- int64_t ratio;
- st_sample_t *buf;
- void *rate;
-
- int wpos;
- int live;
- int active;
- int64_t old_ticks;
- HWVoice *hw;
- char *name;
-};
-
-struct pcm_ops {
- int (*init) (HWVoice *hw, int freq, int nchannels, audfmt_e fmt);
- void (*fini) (HWVoice *hw);
- void (*run) (HWVoice *hw);
- int (*write) (SWVoice *sw, void *buf, int size);
- int (*ctl) (HWVoice *hw, int cmd, ...);
-};
-
-void pcm_sw_free_resources (SWVoice *sw);
-int pcm_sw_alloc_resources (SWVoice *sw);
-void pcm_sw_fini (SWVoice *sw);
-int pcm_sw_init (SWVoice *sw, HWVoice *hw, int freq,
- int nchannels, audfmt_e fmt);
-
-void pcm_hw_clear (HWVoice *hw, void *buf, int len);
-HWVoice * pcm_hw_find_any (HWVoice *hw);
-HWVoice * pcm_hw_find_any_active (HWVoice *hw);
-HWVoice * pcm_hw_find_any_passive (HWVoice *hw);
-HWVoice * pcm_hw_find_specific (HWVoice *hw, int freq,
- int nchannels, audfmt_e fmt);
-HWVoice * pcm_hw_add (int freq, int nchannels, audfmt_e fmt);
-int pcm_hw_add_sw (HWVoice *hw, SWVoice *sw);
-int pcm_hw_del_sw (HWVoice *hw, SWVoice *sw);
-SWVoice * pcm_create_voice_pair (int freq, int nchannels, audfmt_e fmt);
-
-void pcm_hw_free_resources (HWVoice *hw);
-int pcm_hw_alloc_resources (HWVoice *hw);
-void pcm_hw_fini (HWVoice *hw);
-void pcm_hw_gc (HWVoice *hw);
-int pcm_hw_get_live (HWVoice *hw);
-int pcm_hw_get_live2 (HWVoice *hw, int *nb_active);
-void pcm_hw_dec_live (HWVoice *hw, int decr);
-int pcm_hw_write (SWVoice *sw, void *buf, int len);
-
-int audio_get_conf_int (const char *key, int defval);
-const char *audio_get_conf_str (const char *key, const char *defval);
-
-struct audio_output_driver;
-
-#define VOICE_ENABLE 1
-#define VOICE_DISABLE 2
-
-#endif /* audio_int.h */
+++ /dev/null
-/*
- * QEMU Mixing engine
- *
- * Copyright (c) 2004 Vassili Karpov (malc)
- * Copyright (c) 1998 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "vl.h"
-//#define DEBUG_FP
-#include "audio/mixeng.h"
-
-#define IN_T int8_t
-#define IN_MIN CHAR_MIN
-#define IN_MAX CHAR_MAX
-#define SIGNED
-#include "mixeng_template.h"
-#undef SIGNED
-#undef IN_MAX
-#undef IN_MIN
-#undef IN_T
-
-#define IN_T uint8_t
-#define IN_MIN 0
-#define IN_MAX UCHAR_MAX
-#include "mixeng_template.h"
-#undef IN_MAX
-#undef IN_MIN
-#undef IN_T
-
-#define IN_T int16_t
-#define IN_MIN SHRT_MIN
-#define IN_MAX SHRT_MAX
-#define SIGNED
-#include "mixeng_template.h"
-#undef SIGNED
-#undef IN_MAX
-#undef IN_MIN
-#undef IN_T
-
-#define IN_T uint16_t
-#define IN_MIN 0
-#define IN_MAX USHRT_MAX
-#include "mixeng_template.h"
-#undef IN_MAX
-#undef IN_MIN
-#undef IN_T
-
-t_sample *mixeng_conv[2][2][2] = {
- {
- {
- conv_uint8_t_to_mono,
- conv_uint16_t_to_mono
- },
- {
- conv_int8_t_to_mono,
- conv_int16_t_to_mono
- }
- },
- {
- {
- conv_uint8_t_to_stereo,
- conv_uint16_t_to_stereo
- },
- {
- conv_int8_t_to_stereo,
- conv_int16_t_to_stereo
- }
- }
-};
-
-f_sample *mixeng_clip[2][2][2] = {
- {
- {
- clip_uint8_t_from_mono,
- clip_uint16_t_from_mono
- },
- {
- clip_int8_t_from_mono,
- clip_int16_t_from_mono
- }
- },
- {
- {
- clip_uint8_t_from_stereo,
- clip_uint16_t_from_stereo
- },
- {
- clip_int8_t_from_stereo,
- clip_int16_t_from_stereo
- }
- }
-};
-
-/*
- * August 21, 1998
- * Copyright 1998 Fabrice Bellard.
- *
- * [Rewrote completly the code of Lance Norskog And Sundry
- * Contributors with a more efficient algorithm.]
- *
- * This source code is freely redistributable and may be used for
- * any purpose. This copyright notice must be maintained.
- * Lance Norskog And Sundry Contributors are not responsible for
- * the consequences of using this software.
- */
-
-/*
- * Sound Tools rate change effect file.
- */
-/*
- * Linear Interpolation.
- *
- * The use of fractional increment allows us to use no buffer. It
- * avoid the problems at the end of the buffer we had with the old
- * method which stored a possibly big buffer of size
- * lcm(in_rate,out_rate).
- *
- * Limited to 16 bit samples and sampling frequency <= 65535 Hz. If
- * the input & output frequencies are equal, a delay of one sample is
- * introduced. Limited to processing 32-bit count worth of samples.
- *
- * 1 << FRAC_BITS evaluating to zero in several places. Changed with
- * an (unsigned long) cast to make it safe. MarkMLl 2/1/99
- */
-
-/* Private data */
-typedef struct ratestuff {
- uint64_t opos;
- uint64_t opos_inc;
- uint32_t ipos; /* position in the input stream (integer) */
- st_sample_t ilast; /* last sample in the input stream */
-} *rate_t;
-
-/*
- * Prepare processing.
- */
-void *st_rate_start (int inrate, int outrate)
-{
- rate_t rate = (rate_t) qemu_mallocz (sizeof (struct ratestuff));
-
- if (!rate) {
- exit (EXIT_FAILURE);
- }
-
- if (inrate == outrate) {
- // exit (EXIT_FAILURE);
- }
-
- if (inrate >= 65535 || outrate >= 65535) {
- // exit (EXIT_FAILURE);
- }
-
- rate->opos = 0;
-
- /* increment */
- rate->opos_inc = (inrate * ((int64_t) UINT_MAX)) / outrate;
-
- rate->ipos = 0;
- rate->ilast.l = 0;
- rate->ilast.r = 0;
- return rate;
-}
-
-/*
- * Processed signed long samples from ibuf to obuf.
- * Return number of samples processed.
- */
-void st_rate_flow (void *opaque, st_sample_t *ibuf, st_sample_t *obuf,
- int *isamp, int *osamp)
-{
- rate_t rate = (rate_t) opaque;
- st_sample_t *istart, *iend;
- st_sample_t *ostart, *oend;
- st_sample_t ilast, icur, out;
- int64_t t;
-
- ilast = rate->ilast;
-
- istart = ibuf;
- iend = ibuf + *isamp;
-
- ostart = obuf;
- oend = obuf + *osamp;
-
- if (rate->opos_inc == 1ULL << 32) {
- int i, n = *isamp > *osamp ? *osamp : *isamp;
- for (i = 0; i < n; i++) {
- obuf[i].l += ibuf[i].r;
- obuf[i].r += ibuf[i].r;
- }
- *isamp = n;
- *osamp = n;
- return;
- }
-
- while (obuf < oend) {
-
- /* Safety catch to make sure we have input samples. */
- if (ibuf >= iend)
- break;
-
- /* read as many input samples so that ipos > opos */
-
- while (rate->ipos <= (rate->opos >> 32)) {
- ilast = *ibuf++;
- rate->ipos++;
- /* See if we finished the input buffer yet */
- if (ibuf >= iend) goto the_end;
- }
-
- icur = *ibuf;
-
- /* interpolate */
- t = rate->opos & 0xffffffff;
- out.l = (ilast.l * (INT_MAX - t) + icur.l * t) / INT_MAX;
- out.r = (ilast.r * (INT_MAX - t) + icur.r * t) / INT_MAX;
-
- /* output sample & increment position */
-#if 0
- *obuf++ = out;
-#else
- obuf->l += out.l;
- obuf->r += out.r;
- obuf += 1;
-#endif
- rate->opos += rate->opos_inc;
- }
-
-the_end:
- *isamp = ibuf - istart;
- *osamp = obuf - ostart;
- rate->ilast = ilast;
-}
-
-void st_rate_stop (void *opaque)
-{
- qemu_free (opaque);
-}
+++ /dev/null
-/*
- * QEMU Mixing engine header
- *
- * Copyright (c) 2004 Vassili Karpov (malc)
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#ifndef QEMU_MIXENG_H
-#define QEMU_MIXENG_H
-
-typedef void (t_sample) (void *dst, const void *src, int samples);
-typedef void (f_sample) (void *dst, const void *src, int samples);
-typedef struct { int64_t l; int64_t r; } st_sample_t;
-
-extern t_sample *mixeng_conv[2][2][2];
-extern f_sample *mixeng_clip[2][2][2];
-
-void *st_rate_start (int inrate, int outrate);
-void st_rate_flow (void *opaque, st_sample_t *ibuf, st_sample_t *obuf,
- int *isamp, int *osamp);
-void st_rate_stop (void *opaque);
-
-#endif /* mixeng.h */
+++ /dev/null
-/*
- * QEMU Mixing engine
- *
- * Copyright (c) 2004 Vassili Karpov (malc)
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-/*
- * Tusen tack till Mike Nordell
- * dec++'ified by Dscho
- */
-
-#ifdef SIGNED
-#define HALFT IN_MAX
-#define HALF IN_MAX
-#else
-#define HALFT ((IN_MAX)>>1)
-#define HALF HALFT
-#endif
-
-static int64_t inline glue(conv_,IN_T) (IN_T v)
-{
-#ifdef SIGNED
- return (INT_MAX*(int64_t)v)/HALF;
-#else
- return (INT_MAX*((int64_t)v-HALFT))/HALF;
-#endif
-}
-
-static IN_T inline glue(clip_,IN_T) (int64_t v)
-{
- if (v >= INT_MAX)
- return IN_MAX;
- else if (v < -INT_MAX)
- return IN_MIN;
-
-#ifdef SIGNED
- return (IN_T) (v*HALF/INT_MAX);
-#else
- return (IN_T) (v+INT_MAX/2)*HALF/INT_MAX;
-#endif
-}
-
-static void glue(glue(conv_,IN_T),_to_stereo) (void *dst, const void *src,
- int samples)
-{
- st_sample_t *out = (st_sample_t *) dst;
- IN_T *in = (IN_T *) src;
- while (samples--) {
- out->l = glue(conv_,IN_T) (*in++);
- out->r = glue(conv_,IN_T) (*in++);
- out += 1;
- }
-}
-
-static void glue(glue(conv_,IN_T),_to_mono) (void *dst, const void *src,
- int samples)
-{
- st_sample_t *out = (st_sample_t *) dst;
- IN_T *in = (IN_T *) src;
- while (samples--) {
- out->l = glue(conv_,IN_T) (in[0]);
- out->r = out->l;
- out += 1;
- in += 1;
- }
-}
-
-static void glue(glue(clip_,IN_T),_from_stereo) (void *dst, const void *src,
- int samples)
-{
- st_sample_t *in = (st_sample_t *) src;
- IN_T *out = (IN_T *) dst;
- while (samples--) {
- *out++ = glue(clip_,IN_T) (in->l);
- *out++ = glue(clip_,IN_T) (in->r);
- in += 1;
- }
-}
-
-static void glue(glue(clip_,IN_T),_from_mono) (void *dst, const void *src,
- int samples)
-{
- st_sample_t *in = (st_sample_t *) src;
- IN_T *out = (IN_T *) dst;
- while (samples--) {
- *out++ = glue(clip_,IN_T) (in->l + in->r);
- in += 1;
- }
-}
-
-#undef HALF
-#undef HALFT
-
+++ /dev/null
-/*
- * QEMU NULL audio output driver
- *
- * Copyright (c) 2004 Vassili Karpov (malc)
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "vl.h"
-
-#include "audio/audio_int.h"
-
-typedef struct NoVoice {
- HWVoice hw;
- int64_t old_ticks;
-} NoVoice;
-
-#define dolog(...) AUD_log ("noaudio", __VA_ARGS__)
-#ifdef DEBUG
-#define ldebug(...) dolog (__VA_ARGS__)
-#else
-#define ldebug(...)
-#endif
-
-static void no_hw_run (HWVoice *hw)
-{
- NoVoice *no = (NoVoice *) hw;
- int rpos, live, decr, samples;
- st_sample_t *src;
- int64_t now = qemu_get_clock (vm_clock);
- int64_t ticks = now - no->old_ticks;
- int64_t bytes = (ticks * hw->bytes_per_second) / ticks_per_sec;
-
- if (bytes > INT_MAX)
- samples = INT_MAX >> hw->shift;
- else
- samples = bytes >> hw->shift;
-
- live = pcm_hw_get_live (hw);
- if (live <= 0)
- return;
-
- no->old_ticks = now;
- decr = audio_MIN (live, samples);
- samples = decr;
- rpos = hw->rpos;
- while (samples) {
- int left_till_end_samples = hw->samples - rpos;
- int convert_samples = audio_MIN (samples, left_till_end_samples);
-
- src = advance (hw->mix_buf, rpos * sizeof (st_sample_t));
- memset (src, 0, convert_samples * sizeof (st_sample_t));
-
- rpos = (rpos + convert_samples) % hw->samples;
- samples -= convert_samples;
- }
-
- pcm_hw_dec_live (hw, decr);
- hw->rpos = rpos;
-}
-
-static int no_hw_write (SWVoice *sw, void *buf, int len)
-{
- return pcm_hw_write (sw, buf, len);
-}
-
-static int no_hw_init (HWVoice *hw, int freq, int nchannels, audfmt_e fmt)
-{
- hw->freq = freq;
- hw->nchannels = nchannels;
- hw->fmt = fmt;
- hw->bufsize = 4096;
- return 0;
-}
-
-static void no_hw_fini (HWVoice *hw)
-{
- (void) hw;
-}
-
-static int no_hw_ctl (HWVoice *hw, int cmd, ...)
-{
- (void) hw;
- (void) cmd;
- return 0;
-}
-
-static void *no_audio_init (void)
-{
- return &no_audio_init;
-}
-
-static void no_audio_fini (void *opaque)
-{
-}
-
-struct pcm_ops no_pcm_ops = {
- no_hw_init,
- no_hw_fini,
- no_hw_run,
- no_hw_write,
- no_hw_ctl
-};
-
-struct audio_output_driver no_output_driver = {
- "none",
- no_audio_init,
- no_audio_fini,
- &no_pcm_ops,
- 1,
- 1,
- sizeof (NoVoice)
-};
+++ /dev/null
-/*
- * QEMU OSS audio output driver
- *
- * Copyright (c) 2003-2004 Vassili Karpov (malc)
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include <sys/mman.h>
-#include <sys/types.h>
-#include <sys/ioctl.h>
-#include <sys/soundcard.h>
-#include <assert.h>
-#include "vl.h"
-
-#include "audio/audio_int.h"
-
-typedef struct OSSVoice {
- HWVoice hw;
- void *pcm_buf;
- int fd;
- int nfrags;
- int fragsize;
- int mmapped;
- int old_optr;
-} OSSVoice;
-
-#define dolog(...) AUD_log ("oss", __VA_ARGS__)
-#ifdef DEBUG
-#define ldebug(...) dolog (__VA_ARGS__)
-#else
-#define ldebug(...)
-#endif
-
-#define QC_OSS_FRAGSIZE "QEMU_OSS_FRAGSIZE"
-#define QC_OSS_NFRAGS "QEMU_OSS_NFRAGS"
-#define QC_OSS_MMAP "QEMU_OSS_MMAP"
-#define QC_OSS_DEV "QEMU_OSS_DEV"
-
-#define errstr() strerror (errno)
-
-static struct {
- int try_mmap;
- int nfrags;
- int fragsize;
- const char *dspname;
-} conf = {
- .try_mmap = 0,
- .nfrags = 4,
- .fragsize = 4096,
- .dspname = "/dev/dsp"
-};
-
-struct oss_params {
- int freq;
- audfmt_e fmt;
- int nchannels;
- int nfrags;
- int fragsize;
-};
-
-static int oss_hw_write (SWVoice *sw, void *buf, int len)
-{
- return pcm_hw_write (sw, buf, len);
-}
-
-static int AUD_to_ossfmt (audfmt_e fmt)
-{
- switch (fmt) {
- case AUD_FMT_S8: return AFMT_S8;
- case AUD_FMT_U8: return AFMT_U8;
- case AUD_FMT_S16: return AFMT_S16_LE;
- case AUD_FMT_U16: return AFMT_U16_LE;
- default:
- dolog ("Internal logic error: Bad audio format %d\nAborting\n", fmt);
- exit (EXIT_FAILURE);
- }
-}
-
-static int oss_to_audfmt (int fmt)
-{
- switch (fmt) {
- case AFMT_S8: return AUD_FMT_S8;
- case AFMT_U8: return AUD_FMT_U8;
- case AFMT_S16_LE: return AUD_FMT_S16;
- case AFMT_U16_LE: return AUD_FMT_U16;
- default:
- dolog ("Internal logic error: Unrecognized OSS audio format %d\n"
- "Aborting\n",
- fmt);
- exit (EXIT_FAILURE);
- }
-}
-
-#ifdef DEBUG_PCM
-static void oss_dump_pcm_info (struct oss_params *req, struct oss_params *obt)
-{
- dolog ("parameter | requested value | obtained value\n");
- dolog ("format | %10d | %10d\n", req->fmt, obt->fmt);
- dolog ("channels | %10d | %10d\n", req->nchannels, obt->nchannels);
- dolog ("frequency | %10d | %10d\n", req->freq, obt->freq);
- dolog ("nfrags | %10d | %10d\n", req->nfrags, obt->nfrags);
- dolog ("fragsize | %10d | %10d\n", req->fragsize, obt->fragsize);
-}
-#endif
-
-static int oss_open (struct oss_params *req, struct oss_params *obt, int *pfd)
-{
- int fd;
- int mmmmssss;
- audio_buf_info abinfo;
- int fmt, freq, nchannels;
- const char *dspname = conf.dspname;
-
- fd = open (dspname, O_RDWR | O_NONBLOCK);
- if (-1 == fd) {
- dolog ("Could not initialize audio hardware. Failed to open `%s':\n"
- "Reason:%s\n",
- dspname,
- errstr ());
- return -1;
- }
-
- freq = req->freq;
- nchannels = req->nchannels;
- fmt = req->fmt;
-
- if (ioctl (fd, SNDCTL_DSP_SAMPLESIZE, &fmt)) {
- dolog ("Could not initialize audio hardware\n"
- "Failed to set sample size\n"
- "Reason: %s\n",
- errstr ());
- goto err;
- }
-
- if (ioctl (fd, SNDCTL_DSP_CHANNELS, &nchannels)) {
- dolog ("Could not initialize audio hardware\n"
- "Failed to set number of channels\n"
- "Reason: %s\n",
- errstr ());
- goto err;
- }
-
- if (ioctl (fd, SNDCTL_DSP_SPEED, &freq)) {
- dolog ("Could not initialize audio hardware\n"
- "Failed to set frequency\n"
- "Reason: %s\n",
- errstr ());
- goto err;
- }
-
- if (ioctl (fd, SNDCTL_DSP_NONBLOCK)) {
- dolog ("Could not initialize audio hardware\n"
- "Failed to set non-blocking mode\n"
- "Reason: %s\n",
- errstr ());
- goto err;
- }
-
- mmmmssss = (req->nfrags << 16) | lsbindex (req->fragsize);
- if (ioctl (fd, SNDCTL_DSP_SETFRAGMENT, &mmmmssss)) {
- dolog ("Could not initialize audio hardware\n"
- "Failed to set buffer length (%d, %d)\n"
- "Reason:%s\n",
- conf.nfrags, conf.fragsize,
- errstr ());
- goto err;
- }
-
- if (ioctl (fd, SNDCTL_DSP_GETOSPACE, &abinfo)) {
- dolog ("Could not initialize audio hardware\n"
- "Failed to get buffer length\n"
- "Reason:%s\n",
- errstr ());
- goto err;
- }
-
- obt->fmt = fmt;
- obt->nchannels = nchannels;
- obt->freq = freq;
- obt->nfrags = abinfo.fragstotal;
- obt->fragsize = abinfo.fragsize;
- *pfd = fd;
-
- if ((req->fmt != obt->fmt) ||
- (req->nchannels != obt->nchannels) ||
- (req->freq != obt->freq) ||
- (req->fragsize != obt->fragsize) ||
- (req->nfrags != obt->nfrags)) {
-#ifdef DEBUG_PCM
- dolog ("Audio parameters mismatch\n");
- oss_dump_pcm_info (req, obt);
-#endif
- }
-
-#ifdef DEBUG_PCM
- oss_dump_pcm_info (req, obt);
-#endif
- return 0;
-
-err:
- close (fd);
- return -1;
-}
-
-static void oss_hw_run (HWVoice *hw)
-{
- OSSVoice *oss = (OSSVoice *) hw;
- int err, rpos, live, decr;
- int samples;
- uint8_t *dst;
- st_sample_t *src;
- struct audio_buf_info abinfo;
- struct count_info cntinfo;
-
- live = pcm_hw_get_live (hw);
- if (live <= 0)
- return;
-
- if (oss->mmapped) {
- int bytes;
-
- err = ioctl (oss->fd, SNDCTL_DSP_GETOPTR, &cntinfo);
- if (err < 0) {
- dolog ("SNDCTL_DSP_GETOPTR failed\nReason: %s\n", errstr ());
- return;
- }
-
- if (cntinfo.ptr == oss->old_optr) {
- if (abs (hw->samples - live) < 64)
- dolog ("overrun\n");
- return;
- }
-
- if (cntinfo.ptr > oss->old_optr) {
- bytes = cntinfo.ptr - oss->old_optr;
- }
- else {
- bytes = hw->bufsize + cntinfo.ptr - oss->old_optr;
- }
-
- decr = audio_MIN (bytes >> hw->shift, live);
- }
- else {
- err = ioctl (oss->fd, SNDCTL_DSP_GETOSPACE, &abinfo);
- if (err < 0) {
- dolog ("SNDCTL_DSP_GETOSPACE failed\nReason: %s\n", errstr ());
- return;
- }
-
- decr = audio_MIN (abinfo.bytes >> hw->shift, live);
- if (decr <= 0)
- return;
- }
-
- samples = decr;
- rpos = hw->rpos;
- while (samples) {
- int left_till_end_samples = hw->samples - rpos;
- int convert_samples = audio_MIN (samples, left_till_end_samples);
-
- src = advance (hw->mix_buf, rpos * sizeof (st_sample_t));
- dst = advance (oss->pcm_buf, rpos << hw->shift);
-
- hw->clip (dst, src, convert_samples);
- if (!oss->mmapped) {
- int written;
-
- written = write (oss->fd, dst, convert_samples << hw->shift);
- /* XXX: follow errno recommendations ? */
- if (written == -1) {
- dolog ("Failed to write audio\nReason: %s\n", errstr ());
- continue;
- }
-
- if (written != convert_samples << hw->shift) {
- int wsamples = written >> hw->shift;
- int wbytes = wsamples << hw->shift;
- if (wbytes != written) {
- dolog ("Unaligned write %d, %d\n", wbytes, written);
- }
- memset (src, 0, wbytes);
- decr -= samples;
- rpos = (rpos + wsamples) % hw->samples;
- break;
- }
- }
- memset (src, 0, convert_samples * sizeof (st_sample_t));
-
- rpos = (rpos + convert_samples) % hw->samples;
- samples -= convert_samples;
- }
- if (oss->mmapped) {
- oss->old_optr = cntinfo.ptr;
- }
-
- pcm_hw_dec_live (hw, decr);
- hw->rpos = rpos;
-}
-
-static void oss_hw_fini (HWVoice *hw)
-{
- int err;
- OSSVoice *oss = (OSSVoice *) hw;
-
- ldebug ("oss_hw_fini\n");
- err = close (oss->fd);
- if (err) {
- dolog ("Failed to close OSS descriptor\nReason: %s\n", errstr ());
- }
- oss->fd = -1;
-
- if (oss->pcm_buf) {
- if (oss->mmapped) {
- err = munmap (oss->pcm_buf, hw->bufsize);
- if (err) {
- dolog ("Failed to unmap OSS buffer\nReason: %s\n",
- errstr ());
- }
- }
- else {
- qemu_free (oss->pcm_buf);
- }
- oss->pcm_buf = NULL;
- }
-}
-
-static int oss_hw_init (HWVoice *hw, int freq, int nchannels, audfmt_e fmt)
-{
- OSSVoice *oss = (OSSVoice *) hw;
- struct oss_params req, obt;
-
- assert (!oss->fd);
- req.fmt = AUD_to_ossfmt (fmt);
- req.freq = freq;
- req.nchannels = nchannels;
- req.fragsize = conf.fragsize;
- req.nfrags = conf.nfrags;
-
- if (oss_open (&req, &obt, &oss->fd))
- return -1;
-
- hw->freq = obt.freq;
- hw->fmt = oss_to_audfmt (obt.fmt);
- hw->nchannels = obt.nchannels;
-
- oss->nfrags = obt.nfrags;
- oss->fragsize = obt.fragsize;
- hw->bufsize = obt.nfrags * obt.fragsize;
-
- oss->mmapped = 0;
- if (conf.try_mmap) {
- oss->pcm_buf = mmap (0, hw->bufsize, PROT_READ | PROT_WRITE,
- MAP_SHARED, oss->fd, 0);
- if (oss->pcm_buf == MAP_FAILED) {
- dolog ("Failed to mmap OSS device\nReason: %s\n",
- errstr ());
- } else {
- int err;
- int trig = 0;
- if (ioctl (oss->fd, SNDCTL_DSP_SETTRIGGER, &trig) < 0) {
- dolog ("SNDCTL_DSP_SETTRIGGER 0 failed\nReason: %s\n",
- errstr ());
- }
- else {
- trig = PCM_ENABLE_OUTPUT;
- if (ioctl (oss->fd, SNDCTL_DSP_SETTRIGGER, &trig) < 0) {
- dolog ("SNDCTL_DSP_SETTRIGGER PCM_ENABLE_OUTPUT failed\n"
- "Reason: %s\n", errstr ());
- }
- else {
- oss->mmapped = 1;
- }
- }
-
- if (!oss->mmapped) {
- err = munmap (oss->pcm_buf, hw->bufsize);
- if (err) {
- dolog ("Failed to unmap OSS device\nReason: %s\n",
- errstr ());
- }
- }
- }
- }
-
- if (!oss->mmapped) {
- oss->pcm_buf = qemu_mallocz (hw->bufsize);
- if (!oss->pcm_buf) {
- close (oss->fd);
- oss->fd = -1;
- return -1;
- }
- }
-
- return 0;
-}
-
-static int oss_hw_ctl (HWVoice *hw, int cmd, ...)
-{
- int trig;
- OSSVoice *oss = (OSSVoice *) hw;
-
- if (!oss->mmapped)
- return 0;
-
- switch (cmd) {
- case VOICE_ENABLE:
- ldebug ("enabling voice\n");
- pcm_hw_clear (hw, oss->pcm_buf, hw->samples);
- trig = PCM_ENABLE_OUTPUT;
- if (ioctl (oss->fd, SNDCTL_DSP_SETTRIGGER, &trig) < 0) {
- dolog ("SNDCTL_DSP_SETTRIGGER PCM_ENABLE_OUTPUT failed\n"
- "Reason: %s\n", errstr ());
- return -1;
- }
- break;
-
- case VOICE_DISABLE:
- ldebug ("disabling voice\n");
- trig = 0;
- if (ioctl (oss->fd, SNDCTL_DSP_SETTRIGGER, &trig) < 0) {
- dolog ("SNDCTL_DSP_SETTRIGGER 0 failed\nReason: %s\n",
- errstr ());
- return -1;
- }
- break;
- }
- return 0;
-}
-
-static void *oss_audio_init (void)
-{
- conf.fragsize = audio_get_conf_int (QC_OSS_FRAGSIZE, conf.fragsize);
- conf.nfrags = audio_get_conf_int (QC_OSS_NFRAGS, conf.nfrags);
- conf.try_mmap = audio_get_conf_int (QC_OSS_MMAP, conf.try_mmap);
- conf.dspname = audio_get_conf_str (QC_OSS_DEV, conf.dspname);
- return &conf;
-}
-
-static void oss_audio_fini (void *opaque)
-{
-}
-
-struct pcm_ops oss_pcm_ops = {
- oss_hw_init,
- oss_hw_fini,
- oss_hw_run,
- oss_hw_write,
- oss_hw_ctl
-};
-
-struct audio_output_driver oss_output_driver = {
- "oss",
- oss_audio_init,
- oss_audio_fini,
- &oss_pcm_ops,
- 1,
- INT_MAX,
- sizeof (OSSVoice)
-};
+++ /dev/null
-/*
- * QEMU SDL audio output driver
- *
- * Copyright (c) 2004 Vassili Karpov (malc)
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include <SDL.h>
-#include <SDL_thread.h>
-#include "vl.h"
-
-#include "audio/audio_int.h"
-
-typedef struct SDLVoice {
- HWVoice hw;
-} SDLVoice;
-
-#define dolog(...) AUD_log ("sdl", __VA_ARGS__)
-#ifdef DEBUG
-#define ldebug(...) dolog (__VA_ARGS__)
-#else
-#define ldebug(...)
-#endif
-
-#define QC_SDL_SAMPLES "QEMU_SDL_SAMPLES"
-
-#define errstr() SDL_GetError ()
-
-static struct {
- int nb_samples;
-} conf = {
- 1024
-};
-
-struct SDLAudioState {
- int exit;
- SDL_mutex *mutex;
- SDL_sem *sem;
- int initialized;
-} glob_sdl;
-typedef struct SDLAudioState SDLAudioState;
-
-static void sdl_hw_run (HWVoice *hw)
-{
- (void) hw;
-}
-
-static int sdl_lock (SDLAudioState *s)
-{
- if (SDL_LockMutex (s->mutex)) {
- dolog ("SDL_LockMutex failed\nReason: %s\n", errstr ());
- return -1;
- }
- return 0;
-}
-
-static int sdl_unlock (SDLAudioState *s)
-{
- if (SDL_UnlockMutex (s->mutex)) {
- dolog ("SDL_UnlockMutex failed\nReason: %s\n", errstr ());
- return -1;
- }
- return 0;
-}
-
-static int sdl_post (SDLAudioState *s)
-{
- if (SDL_SemPost (s->sem)) {
- dolog ("SDL_SemPost failed\nReason: %s\n", errstr ());
- return -1;
- }
- return 0;
-}
-
-static int sdl_wait (SDLAudioState *s)
-{
- if (SDL_SemWait (s->sem)) {
- dolog ("SDL_SemWait failed\nReason: %s\n", errstr ());
- return -1;
- }
- return 0;
-}
-
-static int sdl_unlock_and_post (SDLAudioState *s)
-{
- if (sdl_unlock (s))
- return -1;
-
- return sdl_post (s);
-}
-
-static int sdl_hw_write (SWVoice *sw, void *buf, int len)
-{
- int ret;
- SDLAudioState *s = &glob_sdl;
- sdl_lock (s);
- ret = pcm_hw_write (sw, buf, len);
- sdl_unlock_and_post (s);
- return ret;
-}
-
-static int AUD_to_sdlfmt (audfmt_e fmt, int *shift)
-{
- *shift = 0;
- switch (fmt) {
- case AUD_FMT_S8: return AUDIO_S8;
- case AUD_FMT_U8: return AUDIO_U8;
- case AUD_FMT_S16: *shift = 1; return AUDIO_S16LSB;
- case AUD_FMT_U16: *shift = 1; return AUDIO_U16LSB;
- default:
- dolog ("Internal logic error: Bad audio format %d\nAborting\n", fmt);
- exit (EXIT_FAILURE);
- }
-}
-
-static int sdl_to_audfmt (int fmt)
-{
- switch (fmt) {
- case AUDIO_S8: return AUD_FMT_S8;
- case AUDIO_U8: return AUD_FMT_U8;
- case AUDIO_S16LSB: return AUD_FMT_S16;
- case AUDIO_U16LSB: return AUD_FMT_U16;
- default:
- dolog ("Internal logic error: Unrecognized SDL audio format %d\n"
- "Aborting\n", fmt);
- exit (EXIT_FAILURE);
- }
-}
-
-static int sdl_open (SDL_AudioSpec *req, SDL_AudioSpec *obt)
-{
- int status;
-
- status = SDL_OpenAudio (req, obt);
- if (status) {
- dolog ("SDL_OpenAudio failed\nReason: %s\n", errstr ());
- }
- return status;
-}
-
-static void sdl_close (SDLAudioState *s)
-{
- if (s->initialized) {
- sdl_lock (s);
- s->exit = 1;
- sdl_unlock_and_post (s);
- SDL_PauseAudio (1);
- SDL_CloseAudio ();
- s->initialized = 0;
- }
-}
-
-static void sdl_callback (void *opaque, Uint8 *buf, int len)
-{
- SDLVoice *sdl = opaque;
- SDLAudioState *s = &glob_sdl;
- HWVoice *hw = &sdl->hw;
- int samples = len >> hw->shift;
-
- if (s->exit) {
- return;
- }
-
- while (samples) {
- int to_mix, live, decr;
-
- /* dolog ("in callback samples=%d\n", samples); */
- sdl_wait (s);
- if (s->exit) {
- return;
- }
-
- sdl_lock (s);
- live = pcm_hw_get_live (hw);
- if (live <= 0)
- goto again;
-
- /* dolog ("in callback live=%d\n", live); */
- to_mix = audio_MIN (samples, live);
- decr = to_mix;
- while (to_mix) {
- int chunk = audio_MIN (to_mix, hw->samples - hw->rpos);
- st_sample_t *src = hw->mix_buf + hw->rpos;
-
- /* dolog ("in callback to_mix %d, chunk %d\n", to_mix, chunk); */
- hw->clip (buf, src, chunk);
- memset (src, 0, chunk * sizeof (st_sample_t));
- hw->rpos = (hw->rpos + chunk) % hw->samples;
- to_mix -= chunk;
- buf += chunk << hw->shift;
- }
- samples -= decr;
- pcm_hw_dec_live (hw, decr);
-
- again:
- sdl_unlock (s);
- }
- /* dolog ("done len=%d\n", len); */
-}
-
-static void sdl_hw_fini (HWVoice *hw)
-{
- ldebug ("sdl_hw_fini %d fixed=%d\n",
- glob_sdl.initialized, audio_conf.fixed_format);
- sdl_close (&glob_sdl);
-}
-
-static int sdl_hw_init (HWVoice *hw, int freq, int nchannels, audfmt_e fmt)
-{
- SDLVoice *sdl = (SDLVoice *) hw;
- SDLAudioState *s = &glob_sdl;
- SDL_AudioSpec req, obt;
- int shift;
-
- ldebug ("sdl_hw_init %d freq=%d fixed=%d\n",
- s->initialized, freq, audio_conf.fixed_format);
-
- if (nchannels != 2) {
- dolog ("Bogus channel count %d\n", nchannels);
- return -1;
- }
-
- req.freq = freq;
- req.format = AUD_to_sdlfmt (fmt, &shift);
- req.channels = nchannels;
- req.samples = conf.nb_samples;
- shift <<= nchannels == 2;
-
- req.callback = sdl_callback;
- req.userdata = sdl;
-
- if (sdl_open (&req, &obt))
- return -1;
-
- hw->freq = obt.freq;
- hw->fmt = sdl_to_audfmt (obt.format);
- hw->nchannels = obt.channels;
- hw->bufsize = obt.samples << shift;
-
- s->initialized = 1;
- s->exit = 0;
- SDL_PauseAudio (0);
- return 0;
-}
-
-static int sdl_hw_ctl (HWVoice *hw, int cmd, ...)
-{
- (void) hw;
-
- switch (cmd) {
- case VOICE_ENABLE:
- SDL_PauseAudio (0);
- break;
-
- case VOICE_DISABLE:
- SDL_PauseAudio (1);
- break;
- }
- return 0;
-}
-
-static void *sdl_audio_init (void)
-{
- SDLAudioState *s = &glob_sdl;
- conf.nb_samples = audio_get_conf_int (QC_SDL_SAMPLES, conf.nb_samples);
-
- if (SDL_InitSubSystem (SDL_INIT_AUDIO)) {
- dolog ("SDL failed to initialize audio subsystem\nReason: %s\n",
- errstr ());
- return NULL;
- }
-
- s->mutex = SDL_CreateMutex ();
- if (!s->mutex) {
- dolog ("Failed to create SDL mutex\nReason: %s\n", errstr ());
- SDL_QuitSubSystem (SDL_INIT_AUDIO);
- return NULL;
- }
-
- s->sem = SDL_CreateSemaphore (0);
- if (!s->sem) {
- dolog ("Failed to create SDL semaphore\nReason: %s\n", errstr ());
- SDL_DestroyMutex (s->mutex);
- SDL_QuitSubSystem (SDL_INIT_AUDIO);
- return NULL;
- }
-
- return s;
-}
-
-static void sdl_audio_fini (void *opaque)
-{
- SDLAudioState *s = opaque;
- sdl_close (s);
- SDL_DestroySemaphore (s->sem);
- SDL_DestroyMutex (s->mutex);
- SDL_QuitSubSystem (SDL_INIT_AUDIO);
-}
-
-struct pcm_ops sdl_pcm_ops = {
- sdl_hw_init,
- sdl_hw_fini,
- sdl_hw_run,
- sdl_hw_write,
- sdl_hw_ctl
-};
-
-struct audio_output_driver sdl_output_driver = {
- "sdl",
- sdl_audio_init,
- sdl_audio_fini,
- &sdl_pcm_ops,
- 1,
- 1,
- sizeof (SDLVoice)
-};
+++ /dev/null
-/*
- * QEMU WAV audio output driver
- *
- * Copyright (c) 2004 Vassili Karpov (malc)
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "vl.h"
-
-#include "audio/audio_int.h"
-
-typedef struct WAVVoice {
- HWVoice hw;
- QEMUFile *f;
- int64_t old_ticks;
- void *pcm_buf;
- int total_samples;
-} WAVVoice;
-
-#define dolog(...) AUD_log ("wav", __VA_ARGS__)
-#ifdef DEBUG
-#define ldebug(...) dolog (__VA_ARGS__)
-#else
-#define ldebug(...)
-#endif
-
-static struct {
- const char *wav_path;
-} conf = {
- .wav_path = "qemu.wav"
-};
-
-static void wav_hw_run (HWVoice *hw)
-{
- WAVVoice *wav = (WAVVoice *) hw;
- int rpos, live, decr, samples;
- uint8_t *dst;
- st_sample_t *src;
- int64_t now = qemu_get_clock (vm_clock);
- int64_t ticks = now - wav->old_ticks;
- int64_t bytes = (ticks * hw->bytes_per_second) / ticks_per_sec;
-
- if (bytes > INT_MAX)
- samples = INT_MAX >> hw->shift;
- else
- samples = bytes >> hw->shift;
-
- live = pcm_hw_get_live (hw);
- if (live <= 0)
- return;
-
- wav->old_ticks = now;
- decr = audio_MIN (live, samples);
- samples = decr;
- rpos = hw->rpos;
- while (samples) {
- int left_till_end_samples = hw->samples - rpos;
- int convert_samples = audio_MIN (samples, left_till_end_samples);
-
- src = advance (hw->mix_buf, rpos * sizeof (st_sample_t));
- dst = advance (wav->pcm_buf, rpos << hw->shift);
-
- hw->clip (dst, src, convert_samples);
- qemu_put_buffer (wav->f, dst, convert_samples << hw->shift);
- memset (src, 0, convert_samples * sizeof (st_sample_t));
-
- rpos = (rpos + convert_samples) % hw->samples;
- samples -= convert_samples;
- wav->total_samples += convert_samples;
- }
-
- pcm_hw_dec_live (hw, decr);
- hw->rpos = rpos;
-}
-
-static int wav_hw_write (SWVoice *sw, void *buf, int len)
-{
- return pcm_hw_write (sw, buf, len);
-}
-
-/* VICE code: Store number as little endian. */
-static void le_store (uint8_t *buf, uint32_t val, int len)
-{
- int i;
- for (i = 0; i < len; i++) {
- buf[i] = (uint8_t) (val & 0xff);
- val >>= 8;
- }
-}
-
-static int wav_hw_init (HWVoice *hw, int freq, int nchannels, audfmt_e fmt)
-{
- WAVVoice *wav = (WAVVoice *) hw;
- int bits16 = 0, stereo = audio_state.fixed_channels == 2;
- uint8_t hdr[] = {
- 0x52, 0x49, 0x46, 0x46, 0x00, 0x00, 0x00, 0x00, 0x57, 0x41, 0x56,
- 0x45, 0x66, 0x6d, 0x74, 0x20, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00,
- 0x02, 0x00, 0x44, 0xac, 0x00, 0x00, 0x10, 0xb1, 0x02, 0x00, 0x04,
- 0x00, 0x10, 0x00, 0x64, 0x61, 0x74, 0x61, 0x00, 0x00, 0x00, 0x00
- };
-
- switch (audio_state.fixed_fmt) {
- case AUD_FMT_S8:
- case AUD_FMT_U8:
- break;
-
- case AUD_FMT_S16:
- case AUD_FMT_U16:
- bits16 = 1;
- break;
- }
-
- hdr[34] = bits16 ? 0x10 : 0x08;
- hw->freq = 44100;
- hw->nchannels = stereo ? 2 : 1;
- hw->fmt = bits16 ? AUD_FMT_S16 : AUD_FMT_U8;
- hw->bufsize = 4096;
- wav->pcm_buf = qemu_mallocz (hw->bufsize);
- if (!wav->pcm_buf)
- return -1;
-
- le_store (hdr + 22, hw->nchannels, 2);
- le_store (hdr + 24, hw->freq, 4);
- le_store (hdr + 28, hw->freq << (bits16 + stereo), 4);
- le_store (hdr + 32, 1 << (bits16 + stereo), 2);
-
- wav->f = fopen (conf.wav_path, "wb");
- if (!wav->f) {
- dolog ("failed to open wave file `%s'\nReason: %s\n",
- conf.wav_path, strerror (errno));
- qemu_free (wav->pcm_buf);
- wav->pcm_buf = NULL;
- return -1;
- }
-
- qemu_put_buffer (wav->f, hdr, sizeof (hdr));
- return 0;
-}
-
-static void wav_hw_fini (HWVoice *hw)
-{
- WAVVoice *wav = (WAVVoice *) hw;
- int stereo = hw->nchannels == 2;
- uint8_t rlen[4];
- uint8_t dlen[4];
- uint32_t rifflen = (wav->total_samples << stereo) + 36;
- uint32_t datalen = wav->total_samples << stereo;
-
- if (!wav->f || !hw->active)
- return;
-
- le_store (rlen, rifflen, 4);
- le_store (dlen, datalen, 4);
-
- qemu_fseek (wav->f, 4, SEEK_SET);
- qemu_put_buffer (wav->f, rlen, 4);
-
- qemu_fseek (wav->f, 32, SEEK_CUR);
- qemu_put_buffer (wav->f, dlen, 4);
-
- fclose (wav->f);
- wav->f = NULL;
-
- qemu_free (wav->pcm_buf);
- wav->pcm_buf = NULL;
-}
-
-static int wav_hw_ctl (HWVoice *hw, int cmd, ...)
-{
- (void) hw;
- (void) cmd;
- return 0;
-}
-
-static void *wav_audio_init (void)
-{
- return &conf;
-}
-
-static void wav_audio_fini (void *opaque)
-{
- ldebug ("wav_fini");
-}
-
-struct pcm_ops wav_pcm_ops = {
- wav_hw_init,
- wav_hw_fini,
- wav_hw_run,
- wav_hw_write,
- wav_hw_ctl
-};
-
-struct audio_output_driver wav_output_driver = {
- "wav",
- wav_audio_init,
- wav_audio_fini,
- &wav_pcm_ops,
- 1,
- 1,
- sizeof (WAVVoice)
-};
+++ /dev/null
-/*
- * QEMU System Emulator block driver
- *
- * Copyright (c) 2004 Johannes E. Schindelin
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "vl.h"
-#include "block_int.h"
-#include <zlib.h>
-
-typedef struct BDRVCloopState {
- int fd;
- uint32_t block_size;
- uint32_t n_blocks;
- uint64_t* offsets;
- uint32_t sectors_per_block;
- uint32_t current_block;
- char* compressed_block;
- char* uncompressed_block;
- z_stream zstream;
-} BDRVCloopState;
-
-static int cloop_probe(const uint8_t *buf, int buf_size, const char *filename)
-{
- const char* magic_version_2_0="#!/bin/sh\n"
- "#V2.0 Format\n"
- "modprobe cloop file=$0 && mount -r -t iso9660 /dev/cloop $1\n";
- int length=strlen(magic_version_2_0);
- if(length>buf_size)
- length=buf_size;
- if(!memcmp(magic_version_2_0,buf,length))
- return 2;
- return 0;
-}
-
-static int cloop_open(BlockDriverState *bs, const char *filename)
-{
- BDRVCloopState *s = bs->opaque;
- uint32_t offsets_size,max_compressed_block_size=1,i;
-
- s->fd = open(filename, O_RDONLY | O_BINARY | O_LARGEFILE);
- if (s->fd < 0)
- return -1;
- bs->read_only = 1;
-
- /* read header */
- if(lseek(s->fd,128,SEEK_SET)<0) {
-cloop_close:
- close(s->fd);
- return -1;
- }
- if(read(s->fd,&s->block_size,4)<4)
- goto cloop_close;
- s->block_size=be32_to_cpu(s->block_size);
- if(read(s->fd,&s->n_blocks,4)<4)
- goto cloop_close;
- s->n_blocks=be32_to_cpu(s->n_blocks);
-
- /* read offsets */
- offsets_size=s->n_blocks*sizeof(uint64_t);
- if(!(s->offsets=(uint64_t*)malloc(offsets_size)))
- goto cloop_close;
- if(read(s->fd,s->offsets,offsets_size)<offsets_size)
- goto cloop_close;
- for(i=0;i<s->n_blocks;i++) {
- s->offsets[i]=be64_to_cpu(s->offsets[i]);
- if(i>0) {
- uint32_t size=s->offsets[i]-s->offsets[i-1];
- if(size>max_compressed_block_size)
- max_compressed_block_size=size;
- }
- }
-
- /* initialize zlib engine */
- if(!(s->compressed_block=(char*)malloc(max_compressed_block_size+1)))
- goto cloop_close;
- if(!(s->uncompressed_block=(char*)malloc(s->block_size)))
- goto cloop_close;
- if(inflateInit(&s->zstream) != Z_OK)
- goto cloop_close;
- s->current_block=s->n_blocks;
-
- s->sectors_per_block = s->block_size/512;
- bs->total_sectors = s->n_blocks*s->sectors_per_block;
- return 0;
-}
-
-static inline int cloop_read_block(BDRVCloopState *s,int block_num)
-{
- if(s->current_block != block_num) {
- int ret;
- uint32_t bytes = s->offsets[block_num+1]-s->offsets[block_num];
-
- lseek(s->fd, s->offsets[block_num], SEEK_SET);
- ret = read(s->fd, s->compressed_block, bytes);
- if (ret != bytes)
- return -1;
-
- s->zstream.next_in = s->compressed_block;
- s->zstream.avail_in = bytes;
- s->zstream.next_out = s->uncompressed_block;
- s->zstream.avail_out = s->block_size;
- ret = inflateReset(&s->zstream);
- if(ret != Z_OK)
- return -1;
- ret = inflate(&s->zstream, Z_FINISH);
- if(ret != Z_STREAM_END || s->zstream.total_out != s->block_size)
- return -1;
-
- s->current_block = block_num;
- }
- return 0;
-}
-
-static int cloop_read(BlockDriverState *bs, int64_t sector_num,
- uint8_t *buf, int nb_sectors)
-{
- BDRVCloopState *s = bs->opaque;
- int i;
-
- for(i=0;i<nb_sectors;i++) {
- uint32_t sector_offset_in_block=((sector_num+i)%s->sectors_per_block),
- block_num=(sector_num+i)/s->sectors_per_block;
- if(cloop_read_block(s, block_num) != 0)
- return -1;
- memcpy(buf+i*512,s->uncompressed_block+sector_offset_in_block*512,512);
- }
- return 0;
-}
-
-static void cloop_close(BlockDriverState *bs)
-{
- BDRVCloopState *s = bs->opaque;
- close(s->fd);
- free(s->compressed_block);
- free(s->uncompressed_block);
- inflateEnd(&s->zstream);
-}
-
-BlockDriver bdrv_cloop = {
- "cloop",
- sizeof(BDRVCloopState),
- cloop_probe,
- cloop_open,
- cloop_read,
- NULL,
- cloop_close,
-};
-
-
+++ /dev/null
-/*
- * Block driver for the COW format
- *
- * Copyright (c) 2004 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#ifndef _WIN32
-#include "vl.h"
-#include "block_int.h"
-#include <sys/mman.h>
-
-/**************************************************************/
-/* COW block driver using file system holes */
-
-/* user mode linux compatible COW file */
-#define COW_MAGIC 0x4f4f4f4d /* MOOO */
-#define COW_VERSION 2
-
-struct cow_header_v2 {
- uint32_t magic;
- uint32_t version;
- char backing_file[1024];
- int32_t mtime;
- uint64_t size;
- uint32_t sectorsize;
-};
-
-typedef struct BDRVCowState {
- int fd;
- uint8_t *cow_bitmap; /* if non NULL, COW mappings are used first */
- uint8_t *cow_bitmap_addr; /* mmap address of cow_bitmap */
- int cow_bitmap_size;
- int64_t cow_sectors_offset;
-} BDRVCowState;
-
-static int cow_probe(const uint8_t *buf, int buf_size, const char *filename)
-{
- const struct cow_header_v2 *cow_header = (const void *)buf;
-
- if (be32_to_cpu(cow_header->magic) == COW_MAGIC &&
- be32_to_cpu(cow_header->version) == COW_VERSION)
- return 100;
- else
- return 0;
-}
-
-static int cow_open(BlockDriverState *bs, const char *filename)
-{
- BDRVCowState *s = bs->opaque;
- int fd;
- struct cow_header_v2 cow_header;
- int64_t size;
-
- fd = open(filename, O_RDWR | O_BINARY | O_LARGEFILE);
- if (fd < 0) {
- fd = open(filename, O_RDONLY | O_BINARY | O_LARGEFILE);
- if (fd < 0)
- return -1;
- }
- s->fd = fd;
- /* see if it is a cow image */
- if (read(fd, &cow_header, sizeof(cow_header)) != sizeof(cow_header)) {
- goto fail;
- }
-
- if (be32_to_cpu(cow_header.magic) != COW_MAGIC ||
- be32_to_cpu(cow_header.version) != COW_VERSION) {
- goto fail;
- }
-
- /* cow image found */
- size = be64_to_cpu(cow_header.size);
- bs->total_sectors = size / 512;
-
- pstrcpy(bs->backing_file, sizeof(bs->backing_file),
- cow_header.backing_file);
-
-#if 0
- if (cow_header.backing_file[0] != '\0') {
- if (stat(cow_header.backing_file, &st) != 0) {
- fprintf(stderr, "%s: could not find original disk image '%s'\n", filename, cow_header.backing_file);
- goto fail;
- }
- if (st.st_mtime != be32_to_cpu(cow_header.mtime)) {
- fprintf(stderr, "%s: original raw disk image '%s' does not match saved timestamp\n", filename, cow_header.backing_file);
- goto fail;
- }
- fd = open(cow_header.backing_file, O_RDONLY | O_LARGEFILE);
- if (fd < 0)
- goto fail;
- bs->fd = fd;
- }
-#endif
- /* mmap the bitmap */
- s->cow_bitmap_size = ((bs->total_sectors + 7) >> 3) + sizeof(cow_header);
- s->cow_bitmap_addr = mmap(get_mmap_addr(s->cow_bitmap_size),
- s->cow_bitmap_size,
- PROT_READ | PROT_WRITE,
- MAP_SHARED, s->fd, 0);
- if (s->cow_bitmap_addr == MAP_FAILED)
- goto fail;
- s->cow_bitmap = s->cow_bitmap_addr + sizeof(cow_header);
- s->cow_sectors_offset = (s->cow_bitmap_size + 511) & ~511;
- return 0;
- fail:
- close(fd);
- return -1;
-}
-
-static inline void set_bit(uint8_t *bitmap, int64_t bitnum)
-{
- bitmap[bitnum / 8] |= (1 << (bitnum%8));
-}
-
-static inline int is_bit_set(const uint8_t *bitmap, int64_t bitnum)
-{
- return !!(bitmap[bitnum / 8] & (1 << (bitnum%8)));
-}
-
-
-/* Return true if first block has been changed (ie. current version is
- * in COW file). Set the number of continuous blocks for which that
- * is true. */
-static inline int is_changed(uint8_t *bitmap,
- int64_t sector_num, int nb_sectors,
- int *num_same)
-{
- int changed;
-
- if (!bitmap || nb_sectors == 0) {
- *num_same = nb_sectors;
- return 0;
- }
-
- changed = is_bit_set(bitmap, sector_num);
- for (*num_same = 1; *num_same < nb_sectors; (*num_same)++) {
- if (is_bit_set(bitmap, sector_num + *num_same) != changed)
- break;
- }
-
- return changed;
-}
-
-static int cow_is_allocated(BlockDriverState *bs, int64_t sector_num,
- int nb_sectors, int *pnum)
-{
- BDRVCowState *s = bs->opaque;
- return is_changed(s->cow_bitmap, sector_num, nb_sectors, pnum);
-}
-
-static int cow_read(BlockDriverState *bs, int64_t sector_num,
- uint8_t *buf, int nb_sectors)
-{
- BDRVCowState *s = bs->opaque;
- int ret, n;
-
- while (nb_sectors > 0) {
- if (is_changed(s->cow_bitmap, sector_num, nb_sectors, &n)) {
- lseek(s->fd, s->cow_sectors_offset + sector_num * 512, SEEK_SET);
- ret = read(s->fd, buf, n * 512);
- if (ret != n * 512)
- return -1;
- } else {
- memset(buf, 0, n * 512);
- }
- nb_sectors -= n;
- sector_num += n;
- buf += n * 512;
- }
- return 0;
-}
-
-static int cow_write(BlockDriverState *bs, int64_t sector_num,
- const uint8_t *buf, int nb_sectors)
-{
- BDRVCowState *s = bs->opaque;
- int ret, i;
-
- lseek(s->fd, s->cow_sectors_offset + sector_num * 512, SEEK_SET);
- ret = write(s->fd, buf, nb_sectors * 512);
- if (ret != nb_sectors * 512)
- return -1;
- for (i = 0; i < nb_sectors; i++)
- set_bit(s->cow_bitmap, sector_num + i);
- return 0;
-}
-
-static void cow_close(BlockDriverState *bs)
-{
- BDRVCowState *s = bs->opaque;
- munmap(s->cow_bitmap_addr, s->cow_bitmap_size);
- close(s->fd);
-}
-
-static int cow_create(const char *filename, int64_t image_sectors,
- const char *image_filename, int flags)
-{
- int fd, cow_fd;
- struct cow_header_v2 cow_header;
- struct stat st;
-
- if (flags)
- return -ENOTSUP;
-
- cow_fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY | O_LARGEFILE,
- 0644);
- if (cow_fd < 0)
- return -1;
- memset(&cow_header, 0, sizeof(cow_header));
- cow_header.magic = cpu_to_be32(COW_MAGIC);
- cow_header.version = cpu_to_be32(COW_VERSION);
- if (image_filename) {
- fd = open(image_filename, O_RDONLY | O_BINARY);
- if (fd < 0) {
- close(cow_fd);
- return -1;
- }
- if (fstat(fd, &st) != 0) {
- close(fd);
- return -1;
- }
- close(fd);
- cow_header.mtime = cpu_to_be32(st.st_mtime);
- realpath(image_filename, cow_header.backing_file);
- }
- cow_header.sectorsize = cpu_to_be32(512);
- cow_header.size = cpu_to_be64(image_sectors * 512);
- write(cow_fd, &cow_header, sizeof(cow_header));
- /* resize to include at least all the bitmap */
- ftruncate(cow_fd, sizeof(cow_header) + ((image_sectors + 7) >> 3));
- close(cow_fd);
- return 0;
-}
-
-BlockDriver bdrv_cow = {
- "cow",
- sizeof(BDRVCowState),
- cow_probe,
- cow_open,
- cow_read,
- cow_write,
- cow_close,
- cow_create,
- cow_is_allocated,
-};
-#endif
+++ /dev/null
-/*
- * Block driver for the QCOW format
- *
- * Copyright (c) 2004 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "vl.h"
-#include "block_int.h"
-#include <zlib.h>
-#include "aes.h"
-
-/**************************************************************/
-/* QEMU COW block driver with compression and encryption support */
-
-#define QCOW_MAGIC (('Q' << 24) | ('F' << 16) | ('I' << 8) | 0xfb)
-#define QCOW_VERSION 1
-
-#define QCOW_CRYPT_NONE 0
-#define QCOW_CRYPT_AES 1
-
-#define QCOW_OFLAG_COMPRESSED (1LL << 63)
-
-typedef struct QCowHeader {
- uint32_t magic;
- uint32_t version;
- uint64_t backing_file_offset;
- uint32_t backing_file_size;
- uint32_t mtime;
- uint64_t size; /* in bytes */
- uint8_t cluster_bits;
- uint8_t l2_bits;
- uint32_t crypt_method;
- uint64_t l1_table_offset;
-} QCowHeader;
-
-#define L2_CACHE_SIZE 16
-
-typedef struct BDRVQcowState {
- int fd;
- int cluster_bits;
- int cluster_size;
- int cluster_sectors;
- int l2_bits;
- int l2_size;
- int l1_size;
- uint64_t cluster_offset_mask;
- uint64_t l1_table_offset;
- uint64_t *l1_table;
- uint64_t *l2_cache;
- uint64_t l2_cache_offsets[L2_CACHE_SIZE];
- uint32_t l2_cache_counts[L2_CACHE_SIZE];
- uint8_t *cluster_cache;
- uint8_t *cluster_data;
- uint64_t cluster_cache_offset;
- uint32_t crypt_method; /* current crypt method, 0 if no key yet */
- uint32_t crypt_method_header;
- AES_KEY aes_encrypt_key;
- AES_KEY aes_decrypt_key;
-} BDRVQcowState;
-
-static int decompress_cluster(BDRVQcowState *s, uint64_t cluster_offset);
-
-static int qcow_probe(const uint8_t *buf, int buf_size, const char *filename)
-{
- const QCowHeader *cow_header = (const void *)buf;
-
- if (be32_to_cpu(cow_header->magic) == QCOW_MAGIC &&
- be32_to_cpu(cow_header->version) == QCOW_VERSION)
- return 100;
- else
- return 0;
-}
-
-static int qcow_open(BlockDriverState *bs, const char *filename)
-{
- BDRVQcowState *s = bs->opaque;
- int fd, len, i, shift;
- QCowHeader header;
-
- fd = open(filename, O_RDWR | O_BINARY | O_LARGEFILE);
- if (fd < 0) {
- fd = open(filename, O_RDONLY | O_BINARY | O_LARGEFILE);
- if (fd < 0)
- return -1;
- }
- s->fd = fd;
- if (read(fd, &header, sizeof(header)) != sizeof(header))
- goto fail;
- be32_to_cpus(&header.magic);
- be32_to_cpus(&header.version);
- be64_to_cpus(&header.backing_file_offset);
- be32_to_cpus(&header.backing_file_size);
- be32_to_cpus(&header.mtime);
- be64_to_cpus(&header.size);
- be32_to_cpus(&header.crypt_method);
- be64_to_cpus(&header.l1_table_offset);
-
- if (header.magic != QCOW_MAGIC || header.version != QCOW_VERSION)
- goto fail;
- if (header.size <= 1 || header.cluster_bits < 9)
- goto fail;
- if (header.crypt_method > QCOW_CRYPT_AES)
- goto fail;
- s->crypt_method_header = header.crypt_method;
- if (s->crypt_method_header)
- bs->encrypted = 1;
- s->cluster_bits = header.cluster_bits;
- s->cluster_size = 1 << s->cluster_bits;
- s->cluster_sectors = 1 << (s->cluster_bits - 9);
- s->l2_bits = header.l2_bits;
- s->l2_size = 1 << s->l2_bits;
- bs->total_sectors = header.size / 512;
- s->cluster_offset_mask = (1LL << (63 - s->cluster_bits)) - 1;
-
- /* read the level 1 table */
- shift = s->cluster_bits + s->l2_bits;
- s->l1_size = (header.size + (1LL << shift) - 1) >> shift;
-
- s->l1_table_offset = header.l1_table_offset;
- s->l1_table = qemu_malloc(s->l1_size * sizeof(uint64_t));
- if (!s->l1_table)
- goto fail;
- lseek(fd, s->l1_table_offset, SEEK_SET);
- if (read(fd, s->l1_table, s->l1_size * sizeof(uint64_t)) !=
- s->l1_size * sizeof(uint64_t))
- goto fail;
- for(i = 0;i < s->l1_size; i++) {
- be64_to_cpus(&s->l1_table[i]);
- }
- /* alloc L2 cache */
- s->l2_cache = qemu_malloc(s->l2_size * L2_CACHE_SIZE * sizeof(uint64_t));
- if (!s->l2_cache)
- goto fail;
- s->cluster_cache = qemu_malloc(s->cluster_size);
- if (!s->cluster_cache)
- goto fail;
- s->cluster_data = qemu_malloc(s->cluster_size);
- if (!s->cluster_data)
- goto fail;
- s->cluster_cache_offset = -1;
-
- /* read the backing file name */
- if (header.backing_file_offset != 0) {
- len = header.backing_file_size;
- if (len > 1023)
- len = 1023;
- lseek(fd, header.backing_file_offset, SEEK_SET);
- if (read(fd, bs->backing_file, len) != len)
- goto fail;
- bs->backing_file[len] = '\0';
- }
- return 0;
-
- fail:
- qemu_free(s->l1_table);
- qemu_free(s->l2_cache);
- qemu_free(s->cluster_cache);
- qemu_free(s->cluster_data);
- close(fd);
- return -1;
-}
-
-static int qcow_set_key(BlockDriverState *bs, const char *key)
-{
- BDRVQcowState *s = bs->opaque;
- uint8_t keybuf[16];
- int len, i;
-
- memset(keybuf, 0, 16);
- len = strlen(key);
- if (len > 16)
- len = 16;
- /* XXX: we could compress the chars to 7 bits to increase
- entropy */
- for(i = 0;i < len;i++) {
- keybuf[i] = key[i];
- }
- s->crypt_method = s->crypt_method_header;
-
- if (AES_set_encrypt_key(keybuf, 128, &s->aes_encrypt_key) != 0)
- return -1;
- if (AES_set_decrypt_key(keybuf, 128, &s->aes_decrypt_key) != 0)
- return -1;
-#if 0
- /* test */
- {
- uint8_t in[16];
- uint8_t out[16];
- uint8_t tmp[16];
- for(i=0;i<16;i++)
- in[i] = i;
- AES_encrypt(in, tmp, &s->aes_encrypt_key);
- AES_decrypt(tmp, out, &s->aes_decrypt_key);
- for(i = 0; i < 16; i++)
- printf(" %02x", tmp[i]);
- printf("\n");
- for(i = 0; i < 16; i++)
- printf(" %02x", out[i]);
- printf("\n");
- }
-#endif
- return 0;
-}
-
-/* The crypt function is compatible with the linux cryptoloop
- algorithm for < 4 GB images. NOTE: out_buf == in_buf is
- supported */
-static void encrypt_sectors(BDRVQcowState *s, int64_t sector_num,
- uint8_t *out_buf, const uint8_t *in_buf,
- int nb_sectors, int enc,
- const AES_KEY *key)
-{
- union {
- uint64_t ll[2];
- uint8_t b[16];
- } ivec;
- int i;
-
- for(i = 0; i < nb_sectors; i++) {
- ivec.ll[0] = cpu_to_le64(sector_num);
- ivec.ll[1] = 0;
- AES_cbc_encrypt(in_buf, out_buf, 512, key,
- ivec.b, enc);
- sector_num++;
- in_buf += 512;
- out_buf += 512;
- }
-}
-
-/* 'allocate' is:
- *
- * 0 to not allocate.
- *
- * 1 to allocate a normal cluster (for sector indexes 'n_start' to
- * 'n_end')
- *
- * 2 to allocate a compressed cluster of size
- * 'compressed_size'. 'compressed_size' must be > 0 and <
- * cluster_size
- *
- * return 0 if not allocated.
- */
-static uint64_t get_cluster_offset(BlockDriverState *bs,
- uint64_t offset, int allocate,
- int compressed_size,
- int n_start, int n_end)
-{
- BDRVQcowState *s = bs->opaque;
- int min_index, i, j, l1_index, l2_index;
- uint64_t l2_offset, *l2_table, cluster_offset, tmp;
- uint32_t min_count;
- int new_l2_table;
-
- l1_index = offset >> (s->l2_bits + s->cluster_bits);
- l2_offset = s->l1_table[l1_index];
- new_l2_table = 0;
- if (!l2_offset) {
- if (!allocate)
- return 0;
- /* allocate a new l2 entry */
- l2_offset = lseek(s->fd, 0, SEEK_END);
- /* round to cluster size */
- l2_offset = (l2_offset + s->cluster_size - 1) & ~(s->cluster_size - 1);
- /* update the L1 entry */
- s->l1_table[l1_index] = l2_offset;
- tmp = cpu_to_be64(l2_offset);
- lseek(s->fd, s->l1_table_offset + l1_index * sizeof(tmp), SEEK_SET);
- if (write(s->fd, &tmp, sizeof(tmp)) != sizeof(tmp))
- return 0;
- new_l2_table = 1;
- }
- for(i = 0; i < L2_CACHE_SIZE; i++) {
- if (l2_offset == s->l2_cache_offsets[i]) {
- /* increment the hit count */
- if (++s->l2_cache_counts[i] == 0xffffffff) {
- for(j = 0; j < L2_CACHE_SIZE; j++) {
- s->l2_cache_counts[j] >>= 1;
- }
- }
- l2_table = s->l2_cache + (i << s->l2_bits);
- goto found;
- }
- }
- /* not found: load a new entry in the least used one */
- min_index = 0;
- min_count = 0xffffffff;
- for(i = 0; i < L2_CACHE_SIZE; i++) {
- if (s->l2_cache_counts[i] < min_count) {
- min_count = s->l2_cache_counts[i];
- min_index = i;
- }
- }
- l2_table = s->l2_cache + (min_index << s->l2_bits);
- lseek(s->fd, l2_offset, SEEK_SET);
- if (new_l2_table) {
- memset(l2_table, 0, s->l2_size * sizeof(uint64_t));
- if (write(s->fd, l2_table, s->l2_size * sizeof(uint64_t)) !=
- s->l2_size * sizeof(uint64_t))
- return 0;
- } else {
- if (read(s->fd, l2_table, s->l2_size * sizeof(uint64_t)) !=
- s->l2_size * sizeof(uint64_t))
- return 0;
- }
- s->l2_cache_offsets[min_index] = l2_offset;
- s->l2_cache_counts[min_index] = 1;
- found:
- l2_index = (offset >> s->cluster_bits) & (s->l2_size - 1);
- cluster_offset = be64_to_cpu(l2_table[l2_index]);
- if (!cluster_offset ||
- ((cluster_offset & QCOW_OFLAG_COMPRESSED) && allocate == 1)) {
- if (!allocate)
- return 0;
- /* allocate a new cluster */
- if ((cluster_offset & QCOW_OFLAG_COMPRESSED) &&
- (n_end - n_start) < s->cluster_sectors) {
- /* if the cluster is already compressed, we must
- decompress it in the case it is not completely
- overwritten */
- if (decompress_cluster(s, cluster_offset) < 0)
- return 0;
- cluster_offset = lseek(s->fd, 0, SEEK_END);
- cluster_offset = (cluster_offset + s->cluster_size - 1) &
- ~(s->cluster_size - 1);
- /* write the cluster content */
- lseek(s->fd, cluster_offset, SEEK_SET);
- if (write(s->fd, s->cluster_cache, s->cluster_size) !=
- s->cluster_size)
- return -1;
- } else {
- cluster_offset = lseek(s->fd, 0, SEEK_END);
- if (allocate == 1) {
- /* round to cluster size */
- cluster_offset = (cluster_offset + s->cluster_size - 1) &
- ~(s->cluster_size - 1);
- ftruncate(s->fd, cluster_offset + s->cluster_size);
- /* if encrypted, we must initialize the cluster
- content which won't be written */
- if (s->crypt_method &&
- (n_end - n_start) < s->cluster_sectors) {
- uint64_t start_sect;
- start_sect = (offset & ~(s->cluster_size - 1)) >> 9;
- memset(s->cluster_data + 512, 0xaa, 512);
- for(i = 0; i < s->cluster_sectors; i++) {
- if (i < n_start || i >= n_end) {
- encrypt_sectors(s, start_sect + i,
- s->cluster_data,
- s->cluster_data + 512, 1, 1,
- &s->aes_encrypt_key);
- lseek(s->fd, cluster_offset + i * 512, SEEK_SET);
- if (write(s->fd, s->cluster_data, 512) != 512)
- return -1;
- }
- }
- }
- } else {
- cluster_offset |= QCOW_OFLAG_COMPRESSED |
- (uint64_t)compressed_size << (63 - s->cluster_bits);
- }
- }
- /* update L2 table */
- tmp = cpu_to_be64(cluster_offset);
- l2_table[l2_index] = tmp;
- lseek(s->fd, l2_offset + l2_index * sizeof(tmp), SEEK_SET);
- if (write(s->fd, &tmp, sizeof(tmp)) != sizeof(tmp))
- return 0;
- }
- return cluster_offset;
-}
-
-static int qcow_is_allocated(BlockDriverState *bs, int64_t sector_num,
- int nb_sectors, int *pnum)
-{
- BDRVQcowState *s = bs->opaque;
- int index_in_cluster, n;
- uint64_t cluster_offset;
-
- cluster_offset = get_cluster_offset(bs, sector_num << 9, 0, 0, 0, 0);
- index_in_cluster = sector_num & (s->cluster_sectors - 1);
- n = s->cluster_sectors - index_in_cluster;
- if (n > nb_sectors)
- n = nb_sectors;
- *pnum = n;
- return (cluster_offset != 0);
-}
-
-static int decompress_buffer(uint8_t *out_buf, int out_buf_size,
- const uint8_t *buf, int buf_size)
-{
- z_stream strm1, *strm = &strm1;
- int ret, out_len;
-
- memset(strm, 0, sizeof(*strm));
-
- strm->next_in = (uint8_t *)buf;
- strm->avail_in = buf_size;
- strm->next_out = out_buf;
- strm->avail_out = out_buf_size;
-
- ret = inflateInit2(strm, -12);
- if (ret != Z_OK)
- return -1;
- ret = inflate(strm, Z_FINISH);
- out_len = strm->next_out - out_buf;
- if ((ret != Z_STREAM_END && ret != Z_BUF_ERROR) ||
- out_len != out_buf_size) {
- inflateEnd(strm);
- return -1;
- }
- inflateEnd(strm);
- return 0;
-}
-
-static int decompress_cluster(BDRVQcowState *s, uint64_t cluster_offset)
-{
- int ret, csize;
- uint64_t coffset;
-
- coffset = cluster_offset & s->cluster_offset_mask;
- if (s->cluster_cache_offset != coffset) {
- csize = cluster_offset >> (63 - s->cluster_bits);
- csize &= (s->cluster_size - 1);
- lseek(s->fd, coffset, SEEK_SET);
- ret = read(s->fd, s->cluster_data, csize);
- if (ret != csize)
- return -1;
- if (decompress_buffer(s->cluster_cache, s->cluster_size,
- s->cluster_data, csize) < 0) {
- return -1;
- }
- s->cluster_cache_offset = coffset;
- }
- return 0;
-}
-
-static int qcow_read(BlockDriverState *bs, int64_t sector_num,
- uint8_t *buf, int nb_sectors)
-{
- BDRVQcowState *s = bs->opaque;
- int ret, index_in_cluster, n;
- uint64_t cluster_offset;
-
- while (nb_sectors > 0) {
- cluster_offset = get_cluster_offset(bs, sector_num << 9, 0, 0, 0, 0);
- index_in_cluster = sector_num & (s->cluster_sectors - 1);
- n = s->cluster_sectors - index_in_cluster;
- if (n > nb_sectors)
- n = nb_sectors;
- if (!cluster_offset) {
- memset(buf, 0, 512 * n);
- } else if (cluster_offset & QCOW_OFLAG_COMPRESSED) {
- if (decompress_cluster(s, cluster_offset) < 0)
- return -1;
- memcpy(buf, s->cluster_cache + index_in_cluster * 512, 512 * n);
- } else {
- lseek(s->fd, cluster_offset + index_in_cluster * 512, SEEK_SET);
- ret = read(s->fd, buf, n * 512);
- if (ret != n * 512)
- return -1;
- if (s->crypt_method) {
- encrypt_sectors(s, sector_num, buf, buf, n, 0,
- &s->aes_decrypt_key);
- }
- }
- nb_sectors -= n;
- sector_num += n;
- buf += n * 512;
- }
- return 0;
-}
-
-static int qcow_write(BlockDriverState *bs, int64_t sector_num,
- const uint8_t *buf, int nb_sectors)
-{
- BDRVQcowState *s = bs->opaque;
- int ret, index_in_cluster, n;
- uint64_t cluster_offset;
-
- while (nb_sectors > 0) {
- index_in_cluster = sector_num & (s->cluster_sectors - 1);
- n = s->cluster_sectors - index_in_cluster;
- if (n > nb_sectors)
- n = nb_sectors;
- cluster_offset = get_cluster_offset(bs, sector_num << 9, 1, 0,
- index_in_cluster,
- index_in_cluster + n);
- if (!cluster_offset)
- return -1;
- lseek(s->fd, cluster_offset + index_in_cluster * 512, SEEK_SET);
- if (s->crypt_method) {
- encrypt_sectors(s, sector_num, s->cluster_data, buf, n, 1,
- &s->aes_encrypt_key);
- ret = write(s->fd, s->cluster_data, n * 512);
- } else {
- ret = write(s->fd, buf, n * 512);
- }
- if (ret != n * 512)
- return -1;
- nb_sectors -= n;
- sector_num += n;
- buf += n * 512;
- }
- s->cluster_cache_offset = -1; /* disable compressed cache */
- return 0;
-}
-
-static void qcow_close(BlockDriverState *bs)
-{
- BDRVQcowState *s = bs->opaque;
- qemu_free(s->l1_table);
- qemu_free(s->l2_cache);
- qemu_free(s->cluster_cache);
- qemu_free(s->cluster_data);
- close(s->fd);
-}
-
-static int qcow_create(const char *filename, int64_t total_size,
- const char *backing_file, int flags)
-{
- int fd, header_size, backing_filename_len, l1_size, i, shift;
- QCowHeader header;
- char backing_filename[1024];
- uint64_t tmp;
- struct stat st;
-
- fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY | O_LARGEFILE,
- 0644);
- if (fd < 0)
- return -1;
- memset(&header, 0, sizeof(header));
- header.magic = cpu_to_be32(QCOW_MAGIC);
- header.version = cpu_to_be32(QCOW_VERSION);
- header.size = cpu_to_be64(total_size * 512);
- header_size = sizeof(header);
- backing_filename_len = 0;
- if (backing_file) {
- realpath(backing_file, backing_filename);
- if (stat(backing_filename, &st) != 0) {
- return -1;
- }
- header.mtime = cpu_to_be32(st.st_mtime);
- header.backing_file_offset = cpu_to_be64(header_size);
- backing_filename_len = strlen(backing_filename);
- header.backing_file_size = cpu_to_be32(backing_filename_len);
- header_size += backing_filename_len;
- header.cluster_bits = 9; /* 512 byte cluster to avoid copying
- unmodifyed sectors */
- header.l2_bits = 12; /* 32 KB L2 tables */
- } else {
- header.cluster_bits = 12; /* 4 KB clusters */
- header.l2_bits = 9; /* 4 KB L2 tables */
- }
- header_size = (header_size + 7) & ~7;
- shift = header.cluster_bits + header.l2_bits;
- l1_size = ((total_size * 512) + (1LL << shift) - 1) >> shift;
-
- header.l1_table_offset = cpu_to_be64(header_size);
- if (flags) {
- header.crypt_method = cpu_to_be32(QCOW_CRYPT_AES);
- } else {
- header.crypt_method = cpu_to_be32(QCOW_CRYPT_NONE);
- }
-
- /* write all the data */
- write(fd, &header, sizeof(header));
- if (backing_file) {
- write(fd, backing_filename, backing_filename_len);
- }
- lseek(fd, header_size, SEEK_SET);
- tmp = 0;
- for(i = 0;i < l1_size; i++) {
- write(fd, &tmp, sizeof(tmp));
- }
- close(fd);
- return 0;
-}
-
-int qcow_get_cluster_size(BlockDriverState *bs)
-{
- BDRVQcowState *s = bs->opaque;
- if (bs->drv != &bdrv_qcow)
- return -1;
- return s->cluster_size;
-}
-
-/* XXX: put compressed sectors first, then all the cluster aligned
- tables to avoid losing bytes in alignment */
-int qcow_compress_cluster(BlockDriverState *bs, int64_t sector_num,
- const uint8_t *buf)
-{
- BDRVQcowState *s = bs->opaque;
- z_stream strm;
- int ret, out_len;
- uint8_t *out_buf;
- uint64_t cluster_offset;
-
- if (bs->drv != &bdrv_qcow)
- return -1;
-
- out_buf = qemu_malloc(s->cluster_size + (s->cluster_size / 1000) + 128);
- if (!out_buf)
- return -1;
-
- /* best compression, small window, no zlib header */
- memset(&strm, 0, sizeof(strm));
- ret = deflateInit2(&strm, Z_DEFAULT_COMPRESSION,
- Z_DEFLATED, -12,
- 9, Z_DEFAULT_STRATEGY);
- if (ret != 0) {
- qemu_free(out_buf);
- return -1;
- }
-
- strm.avail_in = s->cluster_size;
- strm.next_in = (uint8_t *)buf;
- strm.avail_out = s->cluster_size;
- strm.next_out = out_buf;
-
- ret = deflate(&strm, Z_FINISH);
- if (ret != Z_STREAM_END && ret != Z_OK) {
- qemu_free(out_buf);
- deflateEnd(&strm);
- return -1;
- }
- out_len = strm.next_out - out_buf;
-
- deflateEnd(&strm);
-
- if (ret != Z_STREAM_END || out_len >= s->cluster_size) {
- /* could not compress: write normal cluster */
- qcow_write(bs, sector_num, buf, s->cluster_sectors);
- } else {
- cluster_offset = get_cluster_offset(bs, sector_num << 9, 2,
- out_len, 0, 0);
- cluster_offset &= s->cluster_offset_mask;
- lseek(s->fd, cluster_offset, SEEK_SET);
- if (write(s->fd, out_buf, out_len) != out_len) {
- qemu_free(out_buf);
- return -1;
- }
- }
-
- qemu_free(out_buf);
- return 0;
-}
-
-BlockDriver bdrv_qcow = {
- "qcow",
- sizeof(BDRVQcowState),
- qcow_probe,
- qcow_open,
- qcow_read,
- qcow_write,
- qcow_close,
- qcow_create,
- qcow_is_allocated,
- qcow_set_key,
-};
-
-
+++ /dev/null
-/*
- * Block driver for the VMDK format
- *
- * Copyright (c) 2004 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "vl.h"
-#include "block_int.h"
-
-/* XXX: this code is untested */
-/* XXX: add write support */
-
-#define VMDK3_MAGIC (('C' << 24) | ('O' << 16) | ('W' << 8) | 'D')
-#define VMDK4_MAGIC (('K' << 24) | ('D' << 16) | ('M' << 8) | 'V')
-
-typedef struct {
- uint32_t version;
- uint32_t flags;
- uint32_t disk_sectors;
- uint32_t granularity;
- uint32_t l1dir_offset;
- uint32_t l1dir_size;
- uint32_t file_sectors;
- uint32_t cylinders;
- uint32_t heads;
- uint32_t sectors_per_track;
-} VMDK3Header;
-
-typedef struct {
- uint32_t version;
- uint32_t flags;
- int64_t capacity;
- int64_t granularity;
- int64_t desc_offset;
- int64_t desc_size;
- int32_t num_gtes_per_gte;
- int64_t rgd_offset;
- int64_t gd_offset;
- int64_t grain_offset;
- char filler[1];
- char check_bytes[4];
-} VMDK4Header;
-
-#define L2_CACHE_SIZE 16
-
-typedef struct BDRVVmdkState {
- int fd;
- int64_t l1_table_offset;
- uint32_t *l1_table;
- unsigned int l1_size;
- uint32_t l1_entry_sectors;
-
- unsigned int l2_size;
- uint32_t *l2_cache;
- uint32_t l2_cache_offsets[L2_CACHE_SIZE];
- uint32_t l2_cache_counts[L2_CACHE_SIZE];
-
- unsigned int cluster_sectors;
-} BDRVVmdkState;
-
-static int vmdk_probe(const uint8_t *buf, int buf_size, const char *filename)
-{
- uint32_t magic;
-
- if (buf_size < 4)
- return 0;
- magic = be32_to_cpu(*(uint32_t *)buf);
- if (magic == VMDK3_MAGIC ||
- magic == VMDK4_MAGIC)
- return 100;
- else
- return 0;
-}
-
-static int vmdk_open(BlockDriverState *bs, const char *filename)
-{
- BDRVVmdkState *s = bs->opaque;
- int fd, i;
- uint32_t magic;
- int l1_size;
-
- fd = open(filename, O_RDONLY | O_BINARY | O_LARGEFILE);
- if (fd < 0)
- return -1;
- if (read(fd, &magic, sizeof(magic)) != sizeof(magic))
- goto fail;
- magic = be32_to_cpu(magic);
- if (magic == VMDK3_MAGIC) {
- VMDK3Header header;
- if (read(fd, &header, sizeof(header)) !=
- sizeof(header))
- goto fail;
- s->cluster_sectors = le32_to_cpu(header.granularity);
- s->l2_size = 1 << 9;
- s->l1_size = 1 << 6;
- bs->total_sectors = le32_to_cpu(header.disk_sectors);
- s->l1_table_offset = le32_to_cpu(header.l1dir_offset) * 512;
- s->l1_entry_sectors = s->l2_size * s->cluster_sectors;
- } else if (magic == VMDK4_MAGIC) {
- VMDK4Header header;
-
- if (read(fd, &header, sizeof(header)) != sizeof(header))
- goto fail;
- bs->total_sectors = le32_to_cpu(header.capacity);
- s->cluster_sectors = le32_to_cpu(header.granularity);
- s->l2_size = le32_to_cpu(header.num_gtes_per_gte);
- s->l1_entry_sectors = s->l2_size * s->cluster_sectors;
- if (s->l1_entry_sectors <= 0)
- goto fail;
- s->l1_size = (bs->total_sectors + s->l1_entry_sectors - 1)
- / s->l1_entry_sectors;
- s->l1_table_offset = le64_to_cpu(header.rgd_offset) * 512;
- } else {
- goto fail;
- }
- /* read the L1 table */
- l1_size = s->l1_size * sizeof(uint32_t);
- s->l1_table = qemu_malloc(l1_size);
- if (!s->l1_table)
- goto fail;
- if (lseek(fd, s->l1_table_offset, SEEK_SET) == -1)
- goto fail;
- if (read(fd, s->l1_table, l1_size) != l1_size)
- goto fail;
- for(i = 0; i < s->l1_size; i++) {
- le32_to_cpus(&s->l1_table[i]);
- }
-
- s->l2_cache = qemu_malloc(s->l2_size * L2_CACHE_SIZE * sizeof(uint32_t));
- if (!s->l2_cache)
- goto fail;
- s->fd = fd;
- /* XXX: currently only read only */
- bs->read_only = 1;
- return 0;
- fail:
- qemu_free(s->l1_table);
- qemu_free(s->l2_cache);
- close(fd);
- return -1;
-}
-
-static uint64_t get_cluster_offset(BlockDriverState *bs,
- uint64_t offset)
-{
- BDRVVmdkState *s = bs->opaque;
- unsigned int l1_index, l2_offset, l2_index;
- int min_index, i, j;
- uint32_t min_count, *l2_table;
- uint64_t cluster_offset;
-
- l1_index = (offset >> 9) / s->l1_entry_sectors;
- if (l1_index >= s->l1_size)
- return 0;
- l2_offset = s->l1_table[l1_index];
- if (!l2_offset)
- return 0;
-
- for(i = 0; i < L2_CACHE_SIZE; i++) {
- if (l2_offset == s->l2_cache_offsets[i]) {
- /* increment the hit count */
- if (++s->l2_cache_counts[i] == 0xffffffff) {
- for(j = 0; j < L2_CACHE_SIZE; j++) {
- s->l2_cache_counts[j] >>= 1;
- }
- }
- l2_table = s->l2_cache + (i * s->l2_size);
- goto found;
- }
- }
- /* not found: load a new entry in the least used one */
- min_index = 0;
- min_count = 0xffffffff;
- for(i = 0; i < L2_CACHE_SIZE; i++) {
- if (s->l2_cache_counts[i] < min_count) {
- min_count = s->l2_cache_counts[i];
- min_index = i;
- }
- }
- l2_table = s->l2_cache + (min_index * s->l2_size);
- lseek(s->fd, (int64_t)l2_offset * 512, SEEK_SET);
- if (read(s->fd, l2_table, s->l2_size * sizeof(uint32_t)) !=
- s->l2_size * sizeof(uint32_t))
- return 0;
- s->l2_cache_offsets[min_index] = l2_offset;
- s->l2_cache_counts[min_index] = 1;
- found:
- l2_index = ((offset >> 9) / s->cluster_sectors) % s->l2_size;
- cluster_offset = le32_to_cpu(l2_table[l2_index]);
- cluster_offset <<= 9;
- return cluster_offset;
-}
-
-static int vmdk_is_allocated(BlockDriverState *bs, int64_t sector_num,
- int nb_sectors, int *pnum)
-{
- BDRVVmdkState *s = bs->opaque;
- int index_in_cluster, n;
- uint64_t cluster_offset;
-
- cluster_offset = get_cluster_offset(bs, sector_num << 9);
- index_in_cluster = sector_num % s->cluster_sectors;
- n = s->cluster_sectors - index_in_cluster;
- if (n > nb_sectors)
- n = nb_sectors;
- *pnum = n;
- return (cluster_offset != 0);
-}
-
-static int vmdk_read(BlockDriverState *bs, int64_t sector_num,
- uint8_t *buf, int nb_sectors)
-{
- BDRVVmdkState *s = bs->opaque;
- int ret, index_in_cluster, n;
- uint64_t cluster_offset;
-
- while (nb_sectors > 0) {
- cluster_offset = get_cluster_offset(bs, sector_num << 9);
- index_in_cluster = sector_num % s->cluster_sectors;
- n = s->cluster_sectors - index_in_cluster;
- if (n > nb_sectors)
- n = nb_sectors;
- if (!cluster_offset) {
- memset(buf, 0, 512 * n);
- } else {
- lseek(s->fd, cluster_offset + index_in_cluster * 512, SEEK_SET);
- ret = read(s->fd, buf, n * 512);
- if (ret != n * 512)
- return -1;
- }
- nb_sectors -= n;
- sector_num += n;
- buf += n * 512;
- }
- return 0;
-}
-
-static int vmdk_write(BlockDriverState *bs, int64_t sector_num,
- const uint8_t *buf, int nb_sectors)
-{
- return -1;
-}
-
-static void vmdk_close(BlockDriverState *bs)
-{
- BDRVVmdkState *s = bs->opaque;
- qemu_free(s->l1_table);
- qemu_free(s->l2_cache);
- close(s->fd);
-}
-
-BlockDriver bdrv_vmdk = {
- "vmdk",
- sizeof(BDRVVmdkState),
- vmdk_probe,
- vmdk_open,
- vmdk_read,
- vmdk_write,
- vmdk_close,
- NULL, /* no create yet */
- vmdk_is_allocated,
-};
+++ /dev/null
-/*
- * QEMU System Emulator block driver
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "vl.h"
-#include "block_int.h"
-
-static BlockDriverState *bdrv_first;
-static BlockDriver *first_drv;
-
-void bdrv_register(BlockDriver *bdrv)
-{
- bdrv->next = first_drv;
- first_drv = bdrv;
-}
-
-/* create a new block device (by default it is empty) */
-BlockDriverState *bdrv_new(const char *device_name)
-{
- BlockDriverState **pbs, *bs;
-
- bs = qemu_mallocz(sizeof(BlockDriverState));
- if(!bs)
- return NULL;
- pstrcpy(bs->device_name, sizeof(bs->device_name), device_name);
- if (device_name[0] != '\0') {
- /* insert at the end */
- pbs = &bdrv_first;
- while (*pbs != NULL)
- pbs = &(*pbs)->next;
- *pbs = bs;
- }
- return bs;
-}
-
-BlockDriver *bdrv_find_format(const char *format_name)
-{
- BlockDriver *drv1;
- for(drv1 = first_drv; drv1 != NULL; drv1 = drv1->next) {
- if (!strcmp(drv1->format_name, format_name))
- return drv1;
- }
- return NULL;
-}
-
-int bdrv_create(BlockDriver *drv,
- const char *filename, int64_t size_in_sectors,
- const char *backing_file, int flags)
-{
- if (!drv->bdrv_create)
- return -ENOTSUP;
- return drv->bdrv_create(filename, size_in_sectors, backing_file, flags);
-}
-
-static BlockDriver *find_image_format(const char *filename)
-{
- int fd, ret, score, score_max;
- BlockDriver *drv1, *drv;
- uint8_t buf[1024];
-
- fd = open(filename, O_RDONLY | O_BINARY | O_LARGEFILE);
- if (fd < 0)
- return NULL;
- ret = read(fd, buf, sizeof(buf));
- if (ret < 0) {
- close(fd);
- return NULL;
- }
- close(fd);
-
- drv = NULL;
- score_max = 0;
- for(drv1 = first_drv; drv1 != NULL; drv1 = drv1->next) {
- score = drv1->bdrv_probe(buf, ret, filename);
- if (score > score_max) {
- score_max = score;
- drv = drv1;
- }
- }
- return drv;
-}
-
-int bdrv_open(BlockDriverState *bs, const char *filename, int snapshot)
-{
- return bdrv_open2(bs, filename, snapshot, NULL);
-}
-
-int bdrv_open2(BlockDriverState *bs, const char *filename, int snapshot,
- BlockDriver *drv)
-{
- int ret;
-
- bs->read_only = 0;
- bs->is_temporary = 0;
- bs->encrypted = 0;
-
- pstrcpy(bs->filename, sizeof(bs->filename), filename);
- if (!drv) {
- drv = find_image_format(filename);
- if (!drv)
- return -1;
- }
- bs->drv = drv;
- bs->opaque = qemu_mallocz(drv->instance_size);
- if (bs->opaque == NULL && drv->instance_size > 0)
- return -1;
-
- ret = drv->bdrv_open(bs, filename);
- if (ret < 0) {
- qemu_free(bs->opaque);
- return -1;
- }
-#ifndef _WIN32
- if (bs->is_temporary) {
- unlink(filename);
- }
-#endif
- if (bs->backing_file[0] != '\0' && drv->bdrv_is_allocated) {
- /* if there is a backing file, use it */
- bs->backing_hd = bdrv_new("");
- if (!bs->backing_hd) {
- fail:
- bdrv_close(bs);
- return -1;
- }
- if (bdrv_open(bs->backing_hd, bs->backing_file, 0) < 0)
- goto fail;
- }
-
- bs->inserted = 1;
-
- /* call the change callback */
- if (bs->change_cb)
- bs->change_cb(bs->change_opaque);
-
- return 0;
-}
-
-void bdrv_close(BlockDriverState *bs)
-{
- if (bs->inserted) {
- if (bs->backing_hd)
- bdrv_delete(bs->backing_hd);
- bs->drv->bdrv_close(bs);
- qemu_free(bs->opaque);
-#ifdef _WIN32
- if (bs->is_temporary) {
- unlink(bs->filename);
- }
-#endif
- bs->opaque = NULL;
- bs->drv = NULL;
- bs->inserted = 0;
-
- /* call the change callback */
- if (bs->change_cb)
- bs->change_cb(bs->change_opaque);
- }
-}
-
-void bdrv_delete(BlockDriverState *bs)
-{
- /* XXX: remove the driver list */
- bdrv_close(bs);
- qemu_free(bs);
-}
-
-/* commit COW file into the raw image */
-int bdrv_commit(BlockDriverState *bs)
-{
- int64_t i;
- int n, j;
- unsigned char sector[512];
-
- if (!bs->inserted)
- return -ENOENT;
-
- if (bs->read_only) {
- return -EACCES;
- }
-
- if (!bs->backing_hd) {
- return -ENOTSUP;
- }
-
- for (i = 0; i < bs->total_sectors;) {
- if (bs->drv->bdrv_is_allocated(bs, i, 65536, &n)) {
- for(j = 0; j < n; j++) {
- if (bdrv_read(bs, i, sector, 1) != 0) {
- return -EIO;
- }
-
- if (bdrv_write(bs->backing_hd, i, sector, 1) != 0) {
- return -EIO;
- }
- i++;
- }
- } else {
- i += n;
- }
- }
- return 0;
-}
-
-/* return -1 if error */
-int bdrv_read(BlockDriverState *bs, int64_t sector_num,
- uint8_t *buf, int nb_sectors)
-{
- int ret, n;
- BlockDriver *drv = bs->drv;
-
- if (!bs->inserted)
- return -1;
-
- while (nb_sectors > 0) {
- if (sector_num == 0 && bs->boot_sector_enabled) {
- memcpy(buf, bs->boot_sector_data, 512);
- n = 1;
- } else if (bs->backing_hd) {
- if (drv->bdrv_is_allocated(bs, sector_num, nb_sectors, &n)) {
- ret = drv->bdrv_read(bs, sector_num, buf, n);
- if (ret < 0)
- return -1;
- } else {
- /* read from the base image */
- ret = bdrv_read(bs->backing_hd, sector_num, buf, n);
- if (ret < 0)
- return -1;
- }
- } else {
- ret = drv->bdrv_read(bs, sector_num, buf, nb_sectors);
- if (ret < 0)
- return -1;
- /* no need to loop */
- break;
- }
- nb_sectors -= n;
- sector_num += n;
- buf += n * 512;
- }
- return 0;
-}
-
-/* return -1 if error */
-int bdrv_write(BlockDriverState *bs, int64_t sector_num,
- const uint8_t *buf, int nb_sectors)
-{
- if (!bs->inserted)
- return -1;
- if (bs->read_only)
- return -1;
- return bs->drv->bdrv_write(bs, sector_num, buf, nb_sectors);
-}
-
-void bdrv_get_geometry(BlockDriverState *bs, int64_t *nb_sectors_ptr)
-{
- *nb_sectors_ptr = bs->total_sectors;
-}
-
-/* force a given boot sector. */
-void bdrv_set_boot_sector(BlockDriverState *bs, const uint8_t *data, int size)
-{
- bs->boot_sector_enabled = 1;
- if (size > 512)
- size = 512;
- memcpy(bs->boot_sector_data, data, size);
- memset(bs->boot_sector_data + size, 0, 512 - size);
-}
-
-void bdrv_set_geometry_hint(BlockDriverState *bs,
- int cyls, int heads, int secs)
-{
- bs->cyls = cyls;
- bs->heads = heads;
- bs->secs = secs;
-}
-
-void bdrv_set_type_hint(BlockDriverState *bs, int type)
-{
- bs->type = type;
- bs->removable = ((type == BDRV_TYPE_CDROM ||
- type == BDRV_TYPE_FLOPPY));
-}
-
-void bdrv_get_geometry_hint(BlockDriverState *bs,
- int *pcyls, int *pheads, int *psecs)
-{
- *pcyls = bs->cyls;
- *pheads = bs->heads;
- *psecs = bs->secs;
-}
-
-int bdrv_get_type_hint(BlockDriverState *bs)
-{
- return bs->type;
-}
-
-int bdrv_is_removable(BlockDriverState *bs)
-{
- return bs->removable;
-}
-
-int bdrv_is_read_only(BlockDriverState *bs)
-{
- return bs->read_only;
-}
-
-int bdrv_is_inserted(BlockDriverState *bs)
-{
- return bs->inserted;
-}
-
-int bdrv_is_locked(BlockDriverState *bs)
-{
- return bs->locked;
-}
-
-void bdrv_set_locked(BlockDriverState *bs, int locked)
-{
- bs->locked = locked;
-}
-
-void bdrv_set_change_cb(BlockDriverState *bs,
- void (*change_cb)(void *opaque), void *opaque)
-{
- bs->change_cb = change_cb;
- bs->change_opaque = opaque;
-}
-
-int bdrv_is_encrypted(BlockDriverState *bs)
-{
- if (bs->backing_hd && bs->backing_hd->encrypted)
- return 1;
- return bs->encrypted;
-}
-
-int bdrv_set_key(BlockDriverState *bs, const char *key)
-{
- int ret;
- if (bs->backing_hd && bs->backing_hd->encrypted) {
- ret = bdrv_set_key(bs->backing_hd, key);
- if (ret < 0)
- return ret;
- if (!bs->encrypted)
- return 0;
- }
- if (!bs->encrypted || !bs->drv || !bs->drv->bdrv_set_key)
- return -1;
- return bs->drv->bdrv_set_key(bs, key);
-}
-
-void bdrv_get_format(BlockDriverState *bs, char *buf, int buf_size)
-{
- if (!bs->inserted || !bs->drv) {
- buf[0] = '\0';
- } else {
- pstrcpy(buf, buf_size, bs->drv->format_name);
- }
-}
-
-void bdrv_iterate_format(void (*it)(void *opaque, const char *name),
- void *opaque)
-{
- BlockDriver *drv;
-
- for (drv = first_drv; drv != NULL; drv = drv->next) {
- it(opaque, drv->format_name);
- }
-}
-
-BlockDriverState *bdrv_find(const char *name)
-{
- BlockDriverState *bs;
-
- for (bs = bdrv_first; bs != NULL; bs = bs->next) {
- if (!strcmp(name, bs->device_name))
- return bs;
- }
- return NULL;
-}
-
-void bdrv_iterate(void (*it)(void *opaque, const char *name), void *opaque)
-{
- BlockDriverState *bs;
-
- for (bs = bdrv_first; bs != NULL; bs = bs->next) {
- it(opaque, bs->device_name);
- }
-}
-
-const char *bdrv_get_device_name(BlockDriverState *bs)
-{
- return bs->device_name;
-}
-
-void bdrv_info(void)
-{
- BlockDriverState *bs;
-
- for (bs = bdrv_first; bs != NULL; bs = bs->next) {
- term_printf("%s:", bs->device_name);
- term_printf(" type=");
- switch(bs->type) {
- case BDRV_TYPE_HD:
- term_printf("hd");
- break;
- case BDRV_TYPE_CDROM:
- term_printf("cdrom");
- break;
- case BDRV_TYPE_FLOPPY:
- term_printf("floppy");
- break;
- }
- term_printf(" removable=%d", bs->removable);
- if (bs->removable) {
- term_printf(" locked=%d", bs->locked);
- }
- if (bs->inserted) {
- term_printf(" file=%s", bs->filename);
- if (bs->backing_file[0] != '\0')
- term_printf(" backing_file=%s", bs->backing_file);
- term_printf(" ro=%d", bs->read_only);
- term_printf(" drv=%s", bs->drv->format_name);
- if (bs->encrypted)
- term_printf(" encrypted");
- } else {
- term_printf(" [not inserted]");
- }
- term_printf("\n");
- }
-}
-
-
-/**************************************************************/
-/* RAW block driver */
-
-typedef struct BDRVRawState {
- int fd;
-} BDRVRawState;
-
-static int raw_probe(const uint8_t *buf, int buf_size, const char *filename)
-{
- return 1; /* maybe */
-}
-
-static int raw_open(BlockDriverState *bs, const char *filename)
-{
- BDRVRawState *s = bs->opaque;
- int fd;
- int64_t size;
-
- fd = open(filename, O_RDWR | O_BINARY | O_LARGEFILE);
- if (fd < 0) {
- fd = open(filename, O_RDONLY | O_BINARY | O_LARGEFILE);
- if (fd < 0)
- return -1;
- bs->read_only = 1;
- }
- size = lseek(fd, 0, SEEK_END);
- bs->total_sectors = size / 512;
- s->fd = fd;
- return 0;
-}
-
-static int raw_read(BlockDriverState *bs, int64_t sector_num,
- uint8_t *buf, int nb_sectors)
-{
- BDRVRawState *s = bs->opaque;
- int ret;
-
- lseek(s->fd, sector_num * 512, SEEK_SET);
- ret = read(s->fd, buf, nb_sectors * 512);
- if (ret != nb_sectors * 512)
- return -1;
- return 0;
-}
-
-static int raw_write(BlockDriverState *bs, int64_t sector_num,
- const uint8_t *buf, int nb_sectors)
-{
- BDRVRawState *s = bs->opaque;
- int ret;
-
- lseek(s->fd, sector_num * 512, SEEK_SET);
- ret = write(s->fd, buf, nb_sectors * 512);
- if (ret != nb_sectors * 512)
- return -1;
- return 0;
-}
-
-static void raw_close(BlockDriverState *bs)
-{
- BDRVRawState *s = bs->opaque;
- close(s->fd);
-}
-
-static int raw_create(const char *filename, int64_t total_size,
- const char *backing_file, int flags)
-{
- int fd;
-
- if (flags || backing_file)
- return -ENOTSUP;
-
- fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY | O_LARGEFILE,
- 0644);
- if (fd < 0)
- return -EIO;
- ftruncate(fd, total_size * 512);
- close(fd);
- return 0;
-}
-
-BlockDriver bdrv_raw = {
- "raw",
- sizeof(BDRVRawState),
- raw_probe,
- raw_open,
- raw_read,
- raw_write,
- raw_close,
- raw_create,
-};
-
-void bdrv_init(void)
-{
- bdrv_register(&bdrv_raw);
- bdrv_register(&bdrv_qcow);
- bdrv_register(&bdrv_cloop);
-}
+++ /dev/null
-/*
- * QEMU System Emulator block driver
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#ifndef BLOCK_INT_H
-#define BLOCK_INT_H
-
-struct BlockDriver {
- const char *format_name;
- int instance_size;
- int (*bdrv_probe)(const uint8_t *buf, int buf_size, const char *filename);
- int (*bdrv_open)(BlockDriverState *bs, const char *filename);
- int (*bdrv_read)(BlockDriverState *bs, int64_t sector_num,
- uint8_t *buf, int nb_sectors);
- int (*bdrv_write)(BlockDriverState *bs, int64_t sector_num,
- const uint8_t *buf, int nb_sectors);
- void (*bdrv_close)(BlockDriverState *bs);
- int (*bdrv_create)(const char *filename, int64_t total_sectors,
- const char *backing_file, int flags);
- int (*bdrv_is_allocated)(BlockDriverState *bs, int64_t sector_num,
- int nb_sectors, int *pnum);
- int (*bdrv_set_key)(BlockDriverState *bs, const char *key);
- struct BlockDriver *next;
-};
-
-struct BlockDriverState {
- int64_t total_sectors;
- int read_only; /* if true, the media is read only */
- int inserted; /* if true, the media is present */
- int removable; /* if true, the media can be removed */
- int locked; /* if true, the media cannot temporarily be ejected */
- int encrypted; /* if true, the media is encrypted */
- /* event callback when inserting/removing */
- void (*change_cb)(void *opaque);
- void *change_opaque;
-
- BlockDriver *drv;
- void *opaque;
-
- int boot_sector_enabled;
- uint8_t boot_sector_data[512];
-
- char filename[1024];
- char backing_file[1024]; /* if non zero, the image is a diff of
- this file image */
- int is_temporary;
-
- BlockDriverState *backing_hd;
-
- /* NOTE: the following infos are only hints for real hardware
- drivers. They are not used by the block driver */
- int cyls, heads, secs;
- int type;
- char device_name[32];
- BlockDriverState *next;
-};
-
-#endif /* BLOCK_INT_H */
+++ /dev/null
-#ifndef BSWAP_H
-#define BSWAP_H
-
-#include "config-host.h"
-
-#include <inttypes.h>
-
-#ifdef HAVE_BYTESWAP_H
-#include <byteswap.h>
-#else
-
-#define bswap_16(x) \
-({ \
- uint16_t __x = (x); \
- ((uint16_t)( \
- (((uint16_t)(__x) & (uint16_t)0x00ffU) << 8) | \
- (((uint16_t)(__x) & (uint16_t)0xff00U) >> 8) )); \
-})
-
-#define bswap_32(x) \
-({ \
- uint32_t __x = (x); \
- ((uint32_t)( \
- (((uint32_t)(__x) & (uint32_t)0x000000ffUL) << 24) | \
- (((uint32_t)(__x) & (uint32_t)0x0000ff00UL) << 8) | \
- (((uint32_t)(__x) & (uint32_t)0x00ff0000UL) >> 8) | \
- (((uint32_t)(__x) & (uint32_t)0xff000000UL) >> 24) )); \
-})
-
-#define bswap_64(x) \
-({ \
- uint64_t __x = (x); \
- ((uint64_t)( \
- (uint64_t)(((uint64_t)(__x) & (uint64_t)0x00000000000000ffULL) << 56) | \
- (uint64_t)(((uint64_t)(__x) & (uint64_t)0x000000000000ff00ULL) << 40) | \
- (uint64_t)(((uint64_t)(__x) & (uint64_t)0x0000000000ff0000ULL) << 24) | \
- (uint64_t)(((uint64_t)(__x) & (uint64_t)0x00000000ff000000ULL) << 8) | \
- (uint64_t)(((uint64_t)(__x) & (uint64_t)0x000000ff00000000ULL) >> 8) | \
- (uint64_t)(((uint64_t)(__x) & (uint64_t)0x0000ff0000000000ULL) >> 24) | \
- (uint64_t)(((uint64_t)(__x) & (uint64_t)0x00ff000000000000ULL) >> 40) | \
- (uint64_t)(((uint64_t)(__x) & (uint64_t)0xff00000000000000ULL) >> 56) )); \
-})
-
-#endif /* !HAVE_BYTESWAP_H */
-
-static inline uint16_t bswap16(uint16_t x)
-{
- return bswap_16(x);
-}
-
-static inline uint32_t bswap32(uint32_t x)
-{
- return bswap_32(x);
-}
-
-static inline uint64_t bswap64(uint64_t x)
-{
- return bswap_64(x);
-}
-
-static inline void bswap16s(uint16_t *s)
-{
- *s = bswap16(*s);
-}
-
-static inline void bswap32s(uint32_t *s)
-{
- *s = bswap32(*s);
-}
-
-static inline void bswap64s(uint64_t *s)
-{
- *s = bswap64(*s);
-}
-
-#if defined(WORDS_BIGENDIAN)
-#define be_bswap(v, size) (v)
-#define le_bswap(v, size) bswap ## size(v)
-#define be_bswaps(v, size)
-#define le_bswaps(p, size) *p = bswap ## size(*p);
-#else
-#define le_bswap(v, size) (v)
-#define be_bswap(v, size) bswap ## size(v)
-#define le_bswaps(v, size)
-#define be_bswaps(p, size) *p = bswap ## size(*p);
-#endif
-
-#define CPU_CONVERT(endian, size, type)\
-static inline type endian ## size ## _to_cpu(type v)\
-{\
- return endian ## _bswap(v, size);\
-}\
-\
-static inline type cpu_to_ ## endian ## size(type v)\
-{\
- return endian ## _bswap(v, size);\
-}\
-\
-static inline void endian ## size ## _to_cpus(type *p)\
-{\
- endian ## _bswaps(p, size)\
-}\
-\
-static inline void cpu_to_ ## endian ## size ## s(type *p)\
-{\
- endian ## _bswaps(p, size)\
-}\
-\
-static inline type endian ## size ## _to_cpup(const type *p)\
-{\
- return endian ## size ## _to_cpu(*p);\
-}\
-\
-static inline void cpu_to_ ## endian ## size ## w(type *p, type v)\
-{\
- *p = cpu_to_ ## endian ## size(v);\
-}
-
-CPU_CONVERT(be, 16, uint16_t)
-CPU_CONVERT(be, 32, uint32_t)
-CPU_CONVERT(be, 64, uint64_t)
-
-CPU_CONVERT(le, 16, uint16_t)
-CPU_CONVERT(le, 32, uint32_t)
-CPU_CONVERT(le, 64, uint64_t)
-
-/* unaligned versions (optimized for frequent unaligned accesses)*/
-
-#if defined(__i386__) || defined(__powerpc__)
-
-#define cpu_to_le16wu(p, v) cpu_to_le16w(p, v)
-#define cpu_to_le32wu(p, v) cpu_to_le32w(p, v)
-#define le16_to_cpupu(p) le16_to_cpup(p)
-#define le32_to_cpupu(p) le32_to_cpup(p)
-
-#define cpu_to_be16wu(p, v) cpu_to_be16w(p, v)
-#define cpu_to_be32wu(p, v) cpu_to_be32w(p, v)
-
-#else
-
-static inline void cpu_to_le16wu(uint16_t *p, uint16_t v)
-{
- uint8_t *p1 = (uint8_t *)p;
-
- p1[0] = v;
- p1[1] = v >> 8;
-}
-
-static inline void cpu_to_le32wu(uint32_t *p, uint32_t v)
-{
- uint8_t *p1 = (uint8_t *)p;
-
- p1[0] = v;
- p1[1] = v >> 8;
- p1[2] = v >> 16;
- p1[3] = v >> 24;
-}
-
-static inline uint16_t le16_to_cpupu(const uint16_t *p)
-{
- const uint8_t *p1 = (const uint8_t *)p;
- return p1[0] | (p1[1] << 8);
-}
-
-static inline uint32_t le32_to_cpupu(const uint32_t *p)
-{
- const uint8_t *p1 = (const uint8_t *)p;
- return p1[0] | (p1[1] << 8) | (p1[2] << 16) | (p1[3] << 24);
-}
-
-static inline void cpu_to_be16wu(uint16_t *p, uint16_t v)
-{
- uint8_t *p1 = (uint8_t *)p;
-
- p1[0] = v >> 8;
- p1[1] = v;
-}
-
-static inline void cpu_to_be32wu(uint32_t *p, uint32_t v)
-{
- uint8_t *p1 = (uint8_t *)p;
-
- p1[0] = v >> 24;
- p1[1] = v >> 16;
- p1[2] = v >> 8;
- p1[3] = v;
-}
-
-#endif
-
-#ifdef WORDS_BIGENDIAN
-#define cpu_to_32wu cpu_to_be32wu
-#else
-#define cpu_to_32wu cpu_to_le32wu
-#endif
-
-#undef le_bswap
-#undef be_bswap
-#undef le_bswaps
-#undef be_bswaps
-
-#endif /* BSWAP_H */
+++ /dev/null
-#!/bin/sh
-#
-# qemu configure script (c) 2003 Fabrice Bellard
-#
-# set temporary file name
-if test ! -z "$TMPDIR" ; then
- TMPDIR1="${TMPDIR}"
-elif test ! -z "$TEMPDIR" ; then
- TMPDIR1="${TEMPDIR}"
-else
- TMPDIR1="/tmp"
-fi
-
-TMPC="${TMPDIR1}/qemu-conf-${RANDOM}-$$-${RANDOM}.c"
-TMPO="${TMPDIR1}/qemu-conf-${RANDOM}-$$-${RANDOM}.o"
-TMPE="${TMPDIR1}/qemu-conf-${RANDOM}-$$-${RANDOM}"
-TMPS="${TMPDIR1}/qemu-conf-${RANDOM}-$$-${RANDOM}.S"
-
-# default parameters
-prefix=""
-static="no"
-libdir="lib"
-cross_prefix=""
-cc="gcc"
-host_cc="gcc"
-ar="ar"
-make="make"
-strip="strip"
-cpu=`uname -m`
-target_list="target-i386-dm"
-case "$cpu" in
- i386|i486|i586|i686|i86pc|BePC)
- cpu="i386"
- ;;
- armv4l)
- cpu="armv4l"
- ;;
- alpha)
- cpu="alpha"
- ;;
- "Power Macintosh"|ppc|ppc64)
- cpu="powerpc"
- ;;
- mips)
- cpu="mips"
- ;;
- s390)
- cpu="s390"
- ;;
- sparc)
- cpu="sparc"
- ;;
- sparc64)
- cpu="sparc64"
- ;;
- ia64)
- cpu="ia64"
- ;;
- m68k)
- cpu="m68k"
- ;;
- x86_64|amd64)
- cpu="amd64"
- libdir="lib64"
- ;;
- *)
- cpu="unknown"
- ;;
-esac
-gprof="no"
-bigendian="no"
-mingw32="no"
-EXESUF=""
-gdbstub="no"
-slirp="no"
-adlib="no"
-oss="no"
-fmod="no"
-fmod_lib=""
-fmod_inc=""
-
-# OS specific
-targetos=`uname -s`
-case $targetos in
-MINGW32*)
-mingw32="yes"
-;;
-FreeBSD)
-bsd="yes"
-oss="yes"
-;;
-NetBSD)
-bsd="yes"
-oss="yes"
-;;
-OpenBSD)
-bsd="yes"
-oss="yes"
-;;
-Darwin)
-bsd="yes"
-darwin="yes"
-;;
-*)
-oss="yes"
-;;
-esac
-
-if [ "$bsd" = "yes" ] ; then
- if [ ! "$darwin" = "yes" ] ; then
- make="gmake"
- fi
- target_list="i386-softmmu ppc-softmmu sparc-softmmu"
-fi
-
-# find source path
-# XXX: we assume an absolute path is given when launching configure,
-# except in './configure' case.
-source_path=${0%configure}
-source_path=${source_path%/}
-source_path_used="yes"
-if test -z "$source_path" -o "$source_path" = "." ; then
- source_path=`pwd`
- source_path_used="no"
-fi
-
-for opt do
- case "$opt" in
- --prefix=*) prefix=`echo $opt | cut -d '=' -f 2`
- ;;
- --interp-prefix=*) interp_prefix=`echo $opt | cut -d '=' -f 2`
- ;;
- --source-path=*) source_path=`echo $opt | cut -d '=' -f 2`
- ;;
- --cross-prefix=*) cross_prefix=`echo $opt | cut -d '=' -f 2`
- ;;
- --cc=*) cc=`echo $opt | cut -d '=' -f 2`
- ;;
- --make=*) make=`echo $opt | cut -d '=' -f 2`
- ;;
- --extra-cflags=*) CFLAGS="${opt#--extra-cflags=}"
- ;;
- --extra-ldflags=*) LDFLAGS="${opt#--extra-ldflags=}"
- ;;
- --extra-libs=*) extralibs=${opt#--extra-libs=}
- ;;
- --cpu=*) cpu=`echo $opt | cut -d '=' -f 2`
- ;;
- --target-list=*) target_list=${opt#--target-list=}
- ;;
- --enable-gprof) gprof="yes"
- ;;
- --static) static="yes"
- ;;
- --disable-sdl) sdl="no"
- ;;
- --enable-fmod) fmod="yes"
- ;;
- --fmod-lib=*) fmod_lib=${opt#--fmod-lib=}
- ;;
- --fmod-inc=*) fmod_inc=${opt#--fmod-inc=}
- ;;
- --disable-vnc) vnc="no"
- ;;
- --enable-mingw32) mingw32="yes" ; cross_prefix="i386-mingw32-"
- ;;
- --disable-slirp) slirp="no"
- ;;
- --enable-adlib) adlib="yes"
- ;;
- esac
-done
-
-# Checking for CFLAGS
-if test -z "$CFLAGS"; then
- CFLAGS="-O2"
-fi
-
-cc="${cross_prefix}${cc}"
-ar="${cross_prefix}${ar}"
-strip="${cross_prefix}${strip}"
-
-if test "$mingw32" = "yes" ; then
- target_list="i386-softmmu ppc-softmmu sparc-softmmu"
- EXESUF=".exe"
- gdbstub="no"
- oss="no"
-fi
-
-if test -z "$cross_prefix" ; then
-
-# ---
-# big/little endian test
-cat > $TMPC << EOF
-#include <inttypes.h>
-int main(int argc, char ** argv){
- volatile uint32_t i=0x01234567;
- return (*((uint8_t*)(&i))) == 0x67;
-}
-EOF
-
-if $cc -o $TMPE $TMPC 2>/dev/null ; then
-$TMPE && bigendian="yes"
-else
-echo big/little test failed
-fi
-
-else
-
-# if cross compiling, cannot launch a program, so make a static guess
-if test "$cpu" = "powerpc" -o "$cpu" = "mips" -o "$cpu" = "s390" -o "$cpu" = "sparc" -o "$cpu" = "sparc64" -o "$cpu" = "m68k"; then
- bigendian="yes"
-fi
-
-fi
-
-# check gcc options support
-cat > $TMPC <<EOF
-int main(void) {
-}
-EOF
-
-have_gcc3_options="no"
-if $cc -fno-reorder-blocks -fno-optimize-sibling-calls -o $TMPO $TMPC 2> /dev/null ; then
- have_gcc3_options="yes"
-fi
-
-##########################################
-# VNC probe
-
-if test -z "$vnc"; then
-
-if libvncserver-config --version > /dev/null 2>&1; then
- vnc=yes
-else
- vnc=no
-fi
-
-fi
-
-if test "$vnc" = "yes" ; then
-
-# check for eager event handling
-cat > $TMPC <<EOF
-#include "rfb/rfb.h"
-int main(void) {
- rfbScreenInfoPtr screen;
-
- screen->handleEventsEagerly = 1;
-}
-EOF
-
-if $cc `libvncserver-config --cflags` -o $TMPO $TMPC 2> /dev/null ; then
- have_eager_events="yes"
-else
- echo "!!"
- echo "!! Slow VNC mouse, LibVNCServer doesn't support eager events"
- echo "!!"
- have_eager_events="no"
-fi
-
-fi
-
-##########################################
-# SDL probe
-
-sdl_too_old=no
-
-if test -z "$sdl" ; then
-
-sdl_config="sdl-config"
-sdl=no
-sdl_static=no
-
-if test "$mingw32" = "yes" -a ! -z "$cross_prefix" ; then
-# win32 cross compilation case
- sdl_config="i386-mingw32msvc-sdl-config"
- sdl=yes
-else
-# normal SDL probe
-cat > $TMPC << EOF
-#include <SDL.h>
-#undef main /* We don't want SDL to override our main() */
-int main( void ) { return SDL_Init (SDL_INIT_VIDEO); }
-EOF
-
-if $cc -o $TMPE `$sdl_config --cflags 2> /dev/null` $TMPC `$sdl_config --libs 2> /dev/null` 2> /dev/null ; then
-_sdlversion=`$sdl_config --version | sed 's/[^0-9]//g'`
-if test "$_sdlversion" -lt 121 ; then
-sdl_too_old=yes
-else
-sdl=yes
-fi
-
-# static link with sdl ?
-if test "$sdl" = "yes" ; then
-aa="no"
-`$sdl_config --static-libs | grep \\\-laa > /dev/null` && aa="yes"
-sdl_static_libs=`$sdl_config --static-libs`
-if [ "$aa" = "yes" ] ; then
- sdl_static_libs="$sdl_static_libs `aalib-config --static-libs`"
-fi
-
-if $cc -o $TMPE `$sdl_config --cflags 2> /dev/null` $TMPC $sdl_static_libs 2> /dev/null; then
- sdl_static=yes
-fi
-
-fi # static link
-
-fi # sdl compile test
-
-fi # cross compilation
-fi # -z $sdl
-
-if test x"$1" = x"-h" -o x"$1" = x"--help" ; then
-cat << EOF
-
-Usage: configure [options]
-Options: [defaults in brackets after descriptions]
-
-EOF
-echo "Standard options:"
-echo " --help print this message"
-echo " --prefix=PREFIX install in PREFIX [$prefix]"
-echo " --interp-prefix=PREFIX where to find shared libraries, etc."
-echo " use %M for cpu name [$interp_prefix]"
-echo " --target-list=LIST set target list [$target_list]"
-echo " --disable-vnc disable vnc support (else configure checks"
-echo " for libvncserver-config in your PATH)"
-echo ""
-echo "Advanced options (experts only):"
-echo " --source-path=PATH path of source code [$source_path]"
-echo " --cross-prefix=PREFIX use PREFIX for compile tools [$cross_prefix]"
-echo " --cc=CC use C compiler CC [$cc]"
-echo " --make=MAKE use specified make [$make]"
-echo " --static enable static build [$static]"
-echo " --enable-mingw32 enable Win32 cross compilation with mingw32"
-echo " --enable-fmod enable FMOD audio output driver"
-echo " --fmod-lib path to FMOD library"
-echo " --fmod-inc path to FMOD includes"
-echo ""
-echo "NOTE: The object files are build at the place where configure is launched"
-exit 1
-fi
-
-#installroot=$source_path/../../dist/install
-installroot=
-
-if test "$mingw32" = "yes" ; then
-if test -z "$prefix" ; then
- prefix="/c/Program Files/Qemu"
-fi
-
-mandir="$prefix"
-datadir="$prefix"
-docdir="$prefix"
-bindir="$prefix"
-configdir=""
-else
-if test -z "$prefix" ; then
- prefix="usr/local"
-fi
-mandir="$installroot/$prefix/share/man"
-datadir="$installroot/$prefix/share/xen/qemu"
-docdir="$installroot/$prefix/share/doc/qemu"
-bindir="$installroot/$prefix/bin"
-configdir="$installroot/etc/xen"
-fi
-
-echo "Install prefix $prefix"
-echo "BIOS directory $datadir"
-echo "binary directory $bindir"
-if test "$mingw32" = "no" ; then
-echo "Manual directory $mandir"
-fi
-echo "Source path $source_path"
-echo "C compiler $cc"
-echo "make $make"
-echo "host CPU $cpu"
-echo "host big endian $bigendian"
-echo "target list $target_list"
-echo "gprof enabled $gprof"
-echo "static build $static"
-echo "VNC support $vnc"
-echo "SDL support $sdl"
-echo "SDL static link $sdl_static"
-echo "mingw32 support $mingw32"
-echo "Adlib support $adlib"
-echo -n "FMOD support $fmod"
-if test $fmod = "yes"; then
- echo -n " (lib='$fmod_lib' include='$fmod_inc')"
-fi
-echo ""
-
-if test $sdl_too_old = "yes"; then
-echo "-> Your SDL version is too old - please upgrade to have FFplay/SDL support"
-fi
-if test "$sdl_static" = "no"; then
- echo "WARNING: cannot compile statically with SDL - qemu-fast won't have a graphical output"
-fi
-
-config_mak="config-host.mak"
-config_h="config-host.h"
-
-#echo "Creating $config_mak and $config_h"
-
-echo "# Automatically generated by configure - do not modify" > $config_mak
-echo "/* Automatically generated by configure - do not modify */" > $config_h
-
-echo "prefix=$prefix" >> $config_mak
-echo "bindir=$bindir" >> $config_mak
-echo "mandir=$mandir" >> $config_mak
-echo "datadir=$datadir" >> $config_mak
-echo "docdir=$docdir" >> $config_mak
-echo "configdir=$configdir" >> $config_mak
-echo "LIBDIR=$libdir" >> $config_mak
-echo "#define CONFIG_QEMU_SHAREDIR \"$datadir\"" >> $config_h
-#echo "MAKE=$make" >> $config_mak
-#echo "CC=$cc" >> $config_mak
-#if test "$have_gcc3_options" = "yes" ; then
-# echo "HAVE_GCC3_OPTIONS=yes" >> $config_mak
-#fi
-#echo "HOST_CC=$host_cc" >> $config_mak
-#echo "AR=$ar" >> $config_mak
-#echo "STRIP=$strip -s -R .comment -R .note" >> $config_mak
-#echo "CFLAGS=$CFLAGS" >> $config_mak
-#echo "LDFLAGS=$LDFLAGS" >> $config_mak
-#echo "EXESUF=$EXESUF" >> $config_mak
-
-if test "$bigendian" = "yes" ; then
- echo "WORDS_BIGENDIAN=yes" >> $config_mak
- echo "#define WORDS_BIGENDIAN 1" >> $config_h
-fi
-if test "$mingw32" = "yes" ; then
- echo "CONFIG_WIN32=yes" >> $config_mak
- echo "#define CONFIG_WIN32 1" >> $config_h
-elif test -f "/usr/include/byteswap.h" ; then
- echo "#define HAVE_BYTESWAP_H 1" >> $config_h
-fi
-if test "$darwin" = "yes" ; then
- echo "CONFIG_DARWIN=yes" >> $config_mak
- echo "#define CONFIG_DARWIN 1" >> $config_h
-fi
-if test "$gdbstub" = "yes" ; then
- echo "CONFIG_GDBSTUB=yes" >> $config_mak
- echo "#define CONFIG_GDBSTUB 1" >> $config_h
-fi
-if test "$gprof" = "yes" ; then
- echo "TARGET_GPROF=yes" >> $config_mak
- echo "#define HAVE_GPROF 1" >> $config_h
-fi
-if test "$static" = "yes" ; then
- echo "CONFIG_STATIC=yes" >> $config_mak
- echo "#define CONFIG_STATIC 1" >> $config_h
-fi
-if test "$slirp" = "yes" ; then
- echo "CONFIG_SLIRP=yes" >> $config_mak
- echo "#define CONFIG_SLIRP 1" >> $config_h
-fi
-if test "$adlib" = "yes" ; then
- echo "CONFIG_ADLIB=yes" >> $config_mak
- echo "#define CONFIG_ADLIB 1" >> $config_h
-fi
-if test "$oss" = "yes" ; then
- echo "CONFIG_OSS=yes" >> $config_mak
- echo "#define CONFIG_OSS 1" >> $config_h
-fi
-if test "$fmod" = "yes" ; then
- echo "CONFIG_FMOD=yes" >> $config_mak
- echo "CONFIG_FMOD_LIB=$fmod_lib" >> $config_mak
- echo "CONFIG_FMOD_INC=$fmod_inc" >> $config_mak
- echo "#define CONFIG_FMOD 1" >> $config_h
-fi
-echo -n "VERSION=" >>$config_mak
-head $source_path/VERSION >>$config_mak
-echo "" >>$config_mak
-echo -n "#define QEMU_VERSION \"" >> $config_h
-head $source_path/VERSION >> $config_h
-echo "\"" >> $config_h
-
-echo "SRC_PATH=$source_path" >> $config_mak
-echo "TARGET_DIRS=$target_list" >> $config_mak
-
-# XXX: suppress that
-if [ "$bsd" = "yes" ] ; then
- echo "#define O_LARGEFILE 0" >> $config_h
- echo "#define MAP_ANONYMOUS MAP_ANON" >> $config_h
- echo "#define _BSD 1" >> $config_h
-fi
-
-if test "$vnc" = "yes"; then
- echo "CONFIG_VNC=yes" >> $config_mak
- vnc_cflags=`libvncserver-config --cflags`
- if [ -z $vnc_cflags ]; then
- vnc_cflags="/usr/include"
- fi
- echo "VNC_CFLAGS=$vnc_cflags" >> $config_mak
- if test "$have_eager_events" = "yes" ; then
- echo "#define VNC_EAGER_EVENTS 1" >> $config_h
- fi
-fi
-
-if test "$sdl" = "yes"; then
- echo "CONFIG_SDL=yes" >> $config_mak
- echo "SDL_CFLAGS=`$sdl_config --cflags`" >> $config_mak
-fi
-
-for target in $target_list; do
-
-target_dir="$target"
-config_mak=$target_dir/config.mak
-config_h=$target_dir/config.h
-target_cpu=`echo $target | cut -d '-' -f 2`
-[ "$target_cpu" = "ppc" ] && target_bigendian=yes
-target_softmmu="no"
-if expr $target : '.*-softmmu' > /dev/null ; then
- target_softmmu="yes"
-fi
-#for support 256M guest
-target_softmmu="yes"
-target_user_only="no"
-if expr $target : '.*-user' > /dev/null ; then
- target_user_only="yes"
-fi
-#echo "Creating $config_mak, $config_h and $target_dir/Makefile"
-
-mkdir -p $target_dir
-if test "$target" = "arm-user" ; then
- mkdir -p $target_dir/nwfpe
-fi
-if test "$target_user_only" = "no" ; then
- mkdir -p $target_dir/slirp
-fi
-
-#ln -sf $source_path/Makefile.target $target_dir/Makefile
-
-echo "# Automatically generated by configure - do not modify" > $config_mak
-echo "/* Automatically generated by configure - do not modify */" > $config_h
-
-
-echo "include ../config-host.mak" >> $config_mak
-echo "#include \"../config-host.h\"" >> $config_h
-
-echo "TARGET_ARCH=i386" >> $config_mak
-echo "#define TARGET_ARCH \"i386\"" >> $config_h
-echo "#define TARGET_I386 1" >> $config_h
-
-interp_prefix1=`echo "$interp_prefix" | sed "s/%M/$target_cpu/g"`
-echo "#define CONFIG_QEMU_PREFIX \"$interp_prefix1\"" >> $config_h
-
-if test "$target_bigendian" = "yes" ; then
- echo "TARGET_WORDS_BIGENDIAN=yes" >> $config_mak
- echo "#define TARGET_WORDS_BIGENDIAN 1" >> $config_h
-fi
-if test "$target_softmmu" = "yes" ; then
- echo "CONFIG_SOFTMMU=yes" >> $config_mak
- echo "#define CONFIG_SOFTMMU 1" >> $config_h
-fi
-if test "$target_user_only" = "yes" ; then
- echo "CONFIG_USER_ONLY=yes" >> $config_mak
- echo "#define CONFIG_USER_ONLY 1" >> $config_h
-fi
-
-if test "$target_user_only" = "no"; then
- if test "$vnc" = "yes"; then
- echo "#define CONFIG_VNC 1" >> $config_h
- echo "CONFIG_VNC=yes" >> $config_mak
- echo "VNC_CFLAGS=`libvncserver-config --cflags`" >> $config_mak
- echo "VNC_LIBS=`libvncserver-config --libs`" >> $config_mak
- fi
-fi
-
-# sdl defines
-
-if test "$sdl" = "yes" -a "$target_user_only" = "no"; then
- if test "$target_softmmu" = "no" -o "$static" = "yes"; then
- sdl1=$sdl_static
- else
- sdl1=$sdl
- fi
- if test "$sdl1" = "yes" ; then
- echo "#define CONFIG_SDL 1" >> $config_h
- echo "CONFIG_SDL=yes" >> $config_mak
- if test "$target_softmmu" = "no" -o "$static" = "yes"; then
- echo "SDL_LIBS=$sdl_static_libs" >> $config_mak
- else
- echo "SDL_LIBS=`$sdl_config --libs`" >> $config_mak
- fi
- echo -n "SDL_CFLAGS=`$sdl_config --cflags`" >> $config_mak
- if [ "${aa}" = "yes" ] ; then
- echo -n " `aalib-config --cflags`" >> $config_mak ;
- fi
- echo "" >> $config_mak
- fi
-fi
-
-done # for target in $targets
-
-# build tree in object directory if source path is different from current one
-if test "$source_path_used" = "yes" ; then
- DIRS="tests"
- FILES="Makefile tests/Makefile"
- for dir in $DIRS ; do
- mkdir -p $dir
- done
- for f in $FILES ; do
- ln -sf $source_path/$f $f
- done
-fi
-
-rm -f $TMPO $TMPC $TMPE $TMPS
+++ /dev/null
-/*
- * QEMU graphical console
- *
- * Copyright (c) 2004 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "vl.h"
-
-#define DEFAULT_BACKSCROLL 512
-#define MAX_CONSOLES 12
-
-#define RGBA(r, g, b, a) (((a) << 24) | ((r) << 16) | ((g) << 8) | (b))
-#define RGB(r, g, b) RGBA(r, g, b, 0xff)
-
-typedef struct TextCell {
- uint8_t ch;
- uint8_t bgcol:4;
- uint8_t fgcol:4;
-} TextCell;
-
-#define MAX_ESC_PARAMS 3
-
-enum TTYState {
- TTY_STATE_NORM,
- TTY_STATE_ESC,
- TTY_STATE_CSI,
-};
-
-struct TextConsole {
- int text_console; /* true if text console */
- DisplayState *ds;
- int g_width, g_height;
- int width;
- int height;
- int total_height;
- int backscroll_height;
- int fgcol;
- int bgcol;
- int x, y;
- int y_displayed;
- int y_base;
- TextCell *cells;
-
- enum TTYState state;
- int esc_params[MAX_ESC_PARAMS];
- int nb_esc_params;
-
- /* kbd read handler */
- IOReadHandler *fd_read;
- void *fd_opaque;
-};
-
-static TextConsole *active_console;
-static TextConsole *consoles[MAX_CONSOLES];
-static int nb_consoles = 0;
-
-/* convert a RGBA color to a color index usable in graphic primitives */
-static unsigned int vga_get_color(DisplayState *ds, unsigned int rgba)
-{
- unsigned int r, g, b, color;
-
- switch(ds->depth) {
-#if 0
- case 8:
- r = (rgba >> 16) & 0xff;
- g = (rgba >> 8) & 0xff;
- b = (rgba) & 0xff;
- color = (rgb_to_index[r] * 6 * 6) +
- (rgb_to_index[g] * 6) +
- (rgb_to_index[b]);
- break;
-#endif
- case 15:
- r = (rgba >> 16) & 0xff;
- g = (rgba >> 8) & 0xff;
- b = (rgba) & 0xff;
- color = ((r >> 3) << 10) | ((g >> 3) << 5) | (b >> 3);
- break;
- case 16:
- r = (rgba >> 16) & 0xff;
- g = (rgba >> 8) & 0xff;
- b = (rgba) & 0xff;
- color = ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3);
- break;
- case 32:
- default:
- color = rgba;
- break;
- }
- return color;
-}
-
-static void vga_fill_rect (DisplayState *ds,
- int posx, int posy, int width, int height, uint32_t color)
-{
- uint8_t *d, *d1;
- int x, y, bpp;
-
- bpp = (ds->depth + 7) >> 3;
- d1 = ds->data +
- ds->linesize * posy + bpp * posx;
- for (y = 0; y < height; y++) {
- d = d1;
- switch(bpp) {
- case 1:
- for (x = 0; x < width; x++) {
- *((uint8_t *)d) = color;
- d++;
- }
- break;
- case 2:
- for (x = 0; x < width; x++) {
- *((uint16_t *)d) = color;
- d += 2;
- }
- break;
- case 4:
- for (x = 0; x < width; x++) {
- *((uint32_t *)d) = color;
- d += 4;
- }
- break;
- }
- d1 += ds->linesize;
- }
-}
-
-/* copy from (xs, ys) to (xd, yd) a rectangle of size (w, h) */
-static void vga_bitblt(DisplayState *ds, int xs, int ys, int xd, int yd, int w, int h)
-{
- const uint8_t *s;
- uint8_t *d;
- int wb, y, bpp;
-
- bpp = (ds->depth + 7) >> 3;
- wb = w * bpp;
- if (yd <= ys) {
- s = ds->data +
- ds->linesize * ys + bpp * xs;
- d = ds->data +
- ds->linesize * yd + bpp * xd;
- for (y = 0; y < h; y++) {
- memmove(d, s, wb);
- d += ds->linesize;
- s += ds->linesize;
- }
- } else {
- s = ds->data +
- ds->linesize * (ys + h - 1) + bpp * xs;
- d = ds->data +
- ds->linesize * (yd + h - 1) + bpp * xd;
- for (y = 0; y < h; y++) {
- memmove(d, s, wb);
- d -= ds->linesize;
- s -= ds->linesize;
- }
- }
-}
-
-/***********************************************************/
-/* basic char display */
-
-#define FONT_HEIGHT 16
-#define FONT_WIDTH 8
-
-#include "vgafont.h"
-
-#define cbswap_32(__x) \
-((uint32_t)( \
- (((uint32_t)(__x) & (uint32_t)0x000000ffUL) << 24) | \
- (((uint32_t)(__x) & (uint32_t)0x0000ff00UL) << 8) | \
- (((uint32_t)(__x) & (uint32_t)0x00ff0000UL) >> 8) | \
- (((uint32_t)(__x) & (uint32_t)0xff000000UL) >> 24) ))
-
-#ifdef WORDS_BIGENDIAN
-#define PAT(x) x
-#else
-#define PAT(x) cbswap_32(x)
-#endif
-
-static const uint32_t dmask16[16] = {
- PAT(0x00000000),
- PAT(0x000000ff),
- PAT(0x0000ff00),
- PAT(0x0000ffff),
- PAT(0x00ff0000),
- PAT(0x00ff00ff),
- PAT(0x00ffff00),
- PAT(0x00ffffff),
- PAT(0xff000000),
- PAT(0xff0000ff),
- PAT(0xff00ff00),
- PAT(0xff00ffff),
- PAT(0xffff0000),
- PAT(0xffff00ff),
- PAT(0xffffff00),
- PAT(0xffffffff),
-};
-
-static const uint32_t dmask4[4] = {
- PAT(0x00000000),
- PAT(0x0000ffff),
- PAT(0xffff0000),
- PAT(0xffffffff),
-};
-
-static uint32_t color_table[8];
-
-static const uint32_t color_table_rgb[8] = {
- RGB(0x00, 0x00, 0x00),
- RGB(0xff, 0x00, 0x00),
- RGB(0x00, 0xff, 0x00),
- RGB(0xff, 0xff, 0x00),
- RGB(0x00, 0x00, 0xff),
- RGB(0xff, 0x00, 0xff),
- RGB(0x00, 0xff, 0xff),
- RGB(0xff, 0xff, 0xff),
-};
-
-static inline unsigned int col_expand(DisplayState *ds, unsigned int col)
-{
- switch(ds->depth) {
- case 8:
- col |= col << 8;
- col |= col << 16;
- break;
- case 15:
- case 16:
- col |= col << 16;
- break;
- default:
- break;
- }
-
- return col;
-}
-
-static void vga_putcharxy(DisplayState *ds, int x, int y, int ch,
- unsigned int fgcol, unsigned int bgcol)
-{
- uint8_t *d;
- const uint8_t *font_ptr;
- unsigned int font_data, linesize, xorcol, bpp;
- int i;
-
- bpp = (ds->depth + 7) >> 3;
- d = ds->data +
- ds->linesize * y * FONT_HEIGHT + bpp * x * FONT_WIDTH;
- linesize = ds->linesize;
- font_ptr = vgafont16 + FONT_HEIGHT * ch;
- xorcol = bgcol ^ fgcol;
- switch(ds->depth) {
- case 8:
- for(i = 0; i < FONT_HEIGHT; i++) {
- font_data = *font_ptr++;
- ((uint32_t *)d)[0] = (dmask16[(font_data >> 4)] & xorcol) ^ bgcol;
- ((uint32_t *)d)[1] = (dmask16[(font_data >> 0) & 0xf] & xorcol) ^ bgcol;
- d += linesize;
- }
- break;
- case 16:
- case 15:
- for(i = 0; i < FONT_HEIGHT; i++) {
- font_data = *font_ptr++;
- ((uint32_t *)d)[0] = (dmask4[(font_data >> 6)] & xorcol) ^ bgcol;
- ((uint32_t *)d)[1] = (dmask4[(font_data >> 4) & 3] & xorcol) ^ bgcol;
- ((uint32_t *)d)[2] = (dmask4[(font_data >> 2) & 3] & xorcol) ^ bgcol;
- ((uint32_t *)d)[3] = (dmask4[(font_data >> 0) & 3] & xorcol) ^ bgcol;
- d += linesize;
- }
- break;
- case 32:
- for(i = 0; i < FONT_HEIGHT; i++) {
- font_data = *font_ptr++;
- ((uint32_t *)d)[0] = (-((font_data >> 7)) & xorcol) ^ bgcol;
- ((uint32_t *)d)[1] = (-((font_data >> 6) & 1) & xorcol) ^ bgcol;
- ((uint32_t *)d)[2] = (-((font_data >> 5) & 1) & xorcol) ^ bgcol;
- ((uint32_t *)d)[3] = (-((font_data >> 4) & 1) & xorcol) ^ bgcol;
- ((uint32_t *)d)[4] = (-((font_data >> 3) & 1) & xorcol) ^ bgcol;
- ((uint32_t *)d)[5] = (-((font_data >> 2) & 1) & xorcol) ^ bgcol;
- ((uint32_t *)d)[6] = (-((font_data >> 1) & 1) & xorcol) ^ bgcol;
- ((uint32_t *)d)[7] = (-((font_data >> 0) & 1) & xorcol) ^ bgcol;
- d += linesize;
- }
- break;
- }
-}
-
-static void text_console_resize(TextConsole *s)
-{
- TextCell *cells, *c, *c1;
- int w1, x, y, last_width;
-
- last_width = s->width;
- s->width = s->g_width / FONT_WIDTH;
- s->height = s->g_height / FONT_HEIGHT;
-
- w1 = last_width;
- if (s->width < w1)
- w1 = s->width;
-
- cells = qemu_malloc(s->width * s->total_height * sizeof(TextCell));
- for(y = 0; y < s->total_height; y++) {
- c = &cells[y * s->width];
- if (w1 > 0) {
- c1 = &s->cells[y * last_width];
- for(x = 0; x < w1; x++) {
- *c++ = *c1++;
- }
- }
- for(x = w1; x < s->width; x++) {
- c->ch = ' ';
- c->fgcol = 7;
- c->bgcol = 0;
- c++;
- }
- }
- qemu_free(s->cells);
- s->cells = cells;
-}
-
-static void update_xy(TextConsole *s, int x, int y)
-{
- TextCell *c;
- int y1, y2;
-
- if (s == active_console) {
- y1 = (s->y_base + y) % s->total_height;
- y2 = y1 - s->y_displayed;
- if (y2 < 0)
- y2 += s->total_height;
- if (y2 < s->height) {
- c = &s->cells[y1 * s->width + x];
- vga_putcharxy(s->ds, x, y2, c->ch,
- color_table[c->fgcol], color_table[c->bgcol]);
- dpy_update(s->ds, x * FONT_WIDTH, y2 * FONT_HEIGHT,
- FONT_WIDTH, FONT_HEIGHT);
- }
- }
-}
-
-static void console_show_cursor(TextConsole *s, int show)
-{
- TextCell *c;
- int y, y1;
-
- if (s == active_console) {
- y1 = (s->y_base + s->y) % s->total_height;
- y = y1 - s->y_displayed;
- if (y < 0)
- y += s->total_height;
- if (y < s->height) {
- c = &s->cells[y1 * s->width + s->x];
- if (show) {
- vga_putcharxy(s->ds, s->x, y, c->ch,
- color_table[0], color_table[7]);
- } else {
- vga_putcharxy(s->ds, s->x, y, c->ch,
- color_table[c->fgcol], color_table[c->bgcol]);
- }
- dpy_update(s->ds, s->x * FONT_WIDTH, y * FONT_HEIGHT,
- FONT_WIDTH, FONT_HEIGHT);
- }
- }
-}
-
-static void console_refresh(TextConsole *s)
-{
- TextCell *c;
- int x, y, y1;
-
- if (s != active_console)
- return;
-
- vga_fill_rect(s->ds, 0, 0, s->ds->width, s->ds->height,
- color_table[0]);
- y1 = s->y_displayed;
- for(y = 0; y < s->height; y++) {
- c = s->cells + y1 * s->width;
- for(x = 0; x < s->width; x++) {
- vga_putcharxy(s->ds, x, y, c->ch,
- color_table[c->fgcol], color_table[c->bgcol]);
- c++;
- }
- if (++y1 == s->total_height)
- y1 = 0;
- }
- dpy_update(s->ds, 0, 0, s->ds->width, s->ds->height);
- console_show_cursor(s, 1);
-}
-
-static void console_scroll(int ydelta)
-{
- TextConsole *s;
- int i, y1;
-
- s = active_console;
- if (!s || !s->text_console)
- return;
-
- if (ydelta > 0) {
- for(i = 0; i < ydelta; i++) {
- if (s->y_displayed == s->y_base)
- break;
- if (++s->y_displayed == s->total_height)
- s->y_displayed = 0;
- }
- } else {
- ydelta = -ydelta;
- i = s->backscroll_height;
- if (i > s->total_height - s->height)
- i = s->total_height - s->height;
- y1 = s->y_base - i;
- if (y1 < 0)
- y1 += s->total_height;
- for(i = 0; i < ydelta; i++) {
- if (s->y_displayed == y1)
- break;
- if (--s->y_displayed < 0)
- s->y_displayed = s->total_height - 1;
- }
- }
- console_refresh(s);
-}
-
-static void console_put_lf(TextConsole *s)
-{
- TextCell *c;
- int x, y1;
-
- s->x = 0;
- s->y++;
- if (s->y >= s->height) {
- s->y = s->height - 1;
-
- if (s->y_displayed == s->y_base) {
- if (++s->y_displayed == s->total_height)
- s->y_displayed = 0;
- }
- if (++s->y_base == s->total_height)
- s->y_base = 0;
- if (s->backscroll_height < s->total_height)
- s->backscroll_height++;
- y1 = (s->y_base + s->height - 1) % s->total_height;
- c = &s->cells[y1 * s->width];
- for(x = 0; x < s->width; x++) {
- c->ch = ' ';
- c->fgcol = s->fgcol;
- c->bgcol = s->bgcol;
- c++;
- }
- if (s == active_console && s->y_displayed == s->y_base) {
- vga_bitblt(s->ds, 0, FONT_HEIGHT, 0, 0,
- s->width * FONT_WIDTH,
- (s->height - 1) * FONT_HEIGHT);
- vga_fill_rect(s->ds, 0, (s->height - 1) * FONT_HEIGHT,
- s->width * FONT_WIDTH, FONT_HEIGHT,
- color_table[s->bgcol]);
- dpy_update(s->ds, 0, 0,
- s->width * FONT_WIDTH, s->height * FONT_HEIGHT);
- }
- }
-}
-
-static void console_putchar(TextConsole *s, int ch)
-{
- TextCell *c;
- int y1, i, x;
-
- switch(s->state) {
- case TTY_STATE_NORM:
- switch(ch) {
- case '\r':
- s->x = 0;
- break;
- case '\n':
- console_put_lf(s);
- break;
- case 27:
- s->state = TTY_STATE_ESC;
- break;
- default:
- y1 = (s->y_base + s->y) % s->total_height;
- c = &s->cells[y1 * s->width + s->x];
- c->ch = ch;
- c->fgcol = s->fgcol;
- c->bgcol = s->bgcol;
- update_xy(s, s->x, s->y);
- s->x++;
- if (s->x >= s->width)
- console_put_lf(s);
- break;
- }
- break;
- case TTY_STATE_ESC:
- if (ch == '[') {
- for(i=0;i<MAX_ESC_PARAMS;i++)
- s->esc_params[i] = 0;
- s->nb_esc_params = 0;
- s->state = TTY_STATE_CSI;
- } else {
- s->state = TTY_STATE_NORM;
- }
- break;
- case TTY_STATE_CSI:
- if (ch >= '0' && ch <= '9') {
- if (s->nb_esc_params < MAX_ESC_PARAMS) {
- s->esc_params[s->nb_esc_params] =
- s->esc_params[s->nb_esc_params] * 10 + ch - '0';
- }
- } else {
- s->nb_esc_params++;
- if (ch == ';')
- break;
- s->state = TTY_STATE_NORM;
- switch(ch) {
- case 'D':
- if (s->x > 0)
- s->x--;
- break;
- case 'C':
- if (s->x < (s->width - 1))
- s->x++;
- break;
- case 'K':
- /* clear to eol */
- y1 = (s->y_base + s->y) % s->total_height;
- for(x = s->x; x < s->width; x++) {
- c = &s->cells[y1 * s->width + x];
- c->ch = ' ';
- c->fgcol = s->fgcol;
- c->bgcol = s->bgcol;
- c++;
- update_xy(s, x, s->y);
- }
- break;
- default:
- break;
- }
- break;
- }
- }
-}
-
-void console_select(unsigned int index)
-{
- TextConsole *s;
-
- if (index >= MAX_CONSOLES)
- return;
- s = consoles[index];
- if (s) {
- active_console = s;
- if (s->text_console) {
- if (s->g_width != s->ds->width ||
- s->g_height != s->ds->height) {
- s->g_width = s->ds->width;
- s->g_height = s->ds->height;
- text_console_resize(s);
- }
- console_refresh(s);
- }
- }
-}
-
-static int console_puts(CharDriverState *chr, const uint8_t *buf, int len)
-{
- TextConsole *s = chr->opaque;
- int i;
-
- console_show_cursor(s, 0);
- for(i = 0; i < len; i++) {
- console_putchar(s, buf[i]);
- }
- console_show_cursor(s, 1);
- return len;
-}
-
-static void console_chr_add_read_handler(CharDriverState *chr,
- IOCanRWHandler *fd_can_read,
- IOReadHandler *fd_read, void *opaque)
-{
- TextConsole *s = chr->opaque;
- s->fd_read = fd_read;
- s->fd_opaque = opaque;
-}
-
-static void console_send_event(CharDriverState *chr, int event)
-{
- TextConsole *s = chr->opaque;
- int i;
-
- if (event == CHR_EVENT_FOCUS) {
- for(i = 0; i < nb_consoles; i++) {
- if (consoles[i] == s) {
- console_select(i);
- break;
- }
- }
- }
-}
-
-/* called when an ascii key is pressed */
-void kbd_put_keysym(int keysym)
-{
- TextConsole *s;
- uint8_t buf[16], *q;
- int c;
-
- s = active_console;
- if (!s || !s->text_console)
- return;
-
- switch(keysym) {
- case QEMU_KEY_CTRL_UP:
- console_scroll(-1);
- break;
- case QEMU_KEY_CTRL_DOWN:
- console_scroll(1);
- break;
- case QEMU_KEY_CTRL_PAGEUP:
- console_scroll(-10);
- break;
- case QEMU_KEY_CTRL_PAGEDOWN:
- console_scroll(10);
- break;
- default:
- if (s->fd_read) {
- /* convert the QEMU keysym to VT100 key string */
- q = buf;
- if (keysym >= 0xe100 && keysym <= 0xe11f) {
- *q++ = '\033';
- *q++ = '[';
- c = keysym - 0xe100;
- if (c >= 10)
- *q++ = '0' + (c / 10);
- *q++ = '0' + (c % 10);
- *q++ = '~';
- } else if (keysym >= 0xe120 && keysym <= 0xe17f) {
- *q++ = '\033';
- *q++ = '[';
- *q++ = keysym & 0xff;
- } else {
- *q++ = keysym;
- }
- s->fd_read(s->fd_opaque, buf, q - buf);
- }
- break;
- }
-}
-
-TextConsole *graphic_console_init(DisplayState *ds)
-{
- TextConsole *s;
-
- if (nb_consoles >= MAX_CONSOLES)
- return NULL;
- s = qemu_mallocz(sizeof(TextConsole));
- if (!s) {
- return NULL;
- }
- if (!active_console)
- active_console = s;
- s->ds = ds;
- consoles[nb_consoles++] = s;
- return s;
-}
-
-int is_active_console(TextConsole *s)
-{
- return s == active_console;
-}
-
-CharDriverState *text_console_init(DisplayState *ds)
-{
- CharDriverState *chr;
- TextConsole *s;
- int i;
- static int color_inited;
-
- chr = qemu_mallocz(sizeof(CharDriverState));
- if (!chr)
- return NULL;
- s = graphic_console_init(ds);
- if (!s) {
- free(chr);
- return NULL;
- }
- s->text_console = 1;
- chr->opaque = s;
- chr->chr_write = console_puts;
- chr->chr_add_read_handler = console_chr_add_read_handler;
- chr->chr_send_event = console_send_event;
-
- if (!color_inited) {
- color_inited = 1;
- for(i = 0; i < 8; i++) {
- color_table[i] = col_expand(s->ds,
- vga_get_color(s->ds, color_table_rgb[i]));
- }
- }
- s->y_displayed = 0;
- s->y_base = 0;
- s->total_height = DEFAULT_BACKSCROLL;
- s->x = 0;
- s->y = 0;
- s->fgcol = 7;
- s->bgcol = 0;
- s->g_width = s->ds->width;
- s->g_height = s->ds->height;
- text_console_resize(s);
-
- return chr;
-}
+++ /dev/null
-/*
- * defines common to all virtual CPUs
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#ifndef CPU_ALL_H
-#define CPU_ALL_H
-
-#if defined(__arm__) || defined(__sparc__)
-#define WORDS_ALIGNED
-#endif
-
-/* some important defines:
- *
- * WORDS_ALIGNED : if defined, the host cpu can only make word aligned
- * memory accesses.
- *
- * WORDS_BIGENDIAN : if defined, the host cpu is big endian and
- * otherwise little endian.
- *
- * (TARGET_WORDS_ALIGNED : same for target cpu (not supported yet))
- *
- * TARGET_WORDS_BIGENDIAN : same for target cpu
- */
-
-#include "bswap.h"
-
-#if defined(WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN)
-#define BSWAP_NEEDED
-#endif
-
-#ifdef BSWAP_NEEDED
-
-static inline uint16_t tswap16(uint16_t s)
-{
- return bswap16(s);
-}
-
-static inline uint32_t tswap32(uint32_t s)
-{
- return bswap32(s);
-}
-
-static inline uint64_t tswap64(uint64_t s)
-{
- return bswap64(s);
-}
-
-static inline void tswap16s(uint16_t *s)
-{
- *s = bswap16(*s);
-}
-
-static inline void tswap32s(uint32_t *s)
-{
- *s = bswap32(*s);
-}
-
-static inline void tswap64s(uint64_t *s)
-{
- *s = bswap64(*s);
-}
-
-#else
-
-static inline uint16_t tswap16(uint16_t s)
-{
- return s;
-}
-
-static inline uint32_t tswap32(uint32_t s)
-{
- return s;
-}
-
-static inline uint64_t tswap64(uint64_t s)
-{
- return s;
-}
-
-static inline void tswap16s(uint16_t *s)
-{
-}
-
-static inline void tswap32s(uint32_t *s)
-{
-}
-
-static inline void tswap64s(uint64_t *s)
-{
-}
-
-#endif
-
-#if TARGET_LONG_SIZE == 4
-#define tswapl(s) tswap32(s)
-#define tswapls(s) tswap32s((uint32_t *)(s))
-#else
-#define tswapl(s) tswap64(s)
-#define tswapls(s) tswap64s((uint64_t *)(s))
-#endif
-
-/* NOTE: arm is horrible as double 32 bit words are stored in big endian ! */
-typedef union {
- double d;
-#if !defined(WORDS_BIGENDIAN) && !defined(__arm__)
- struct {
- uint32_t lower;
- uint32_t upper;
- } l;
-#else
- struct {
- uint32_t upper;
- uint32_t lower;
- } l;
-#endif
- uint64_t ll;
-} CPU_DoubleU;
-
-/* CPU memory access without any memory or io remapping */
-
-/*
- * the generic syntax for the memory accesses is:
- *
- * load: ld{type}{sign}{size}{endian}_{access_type}(ptr)
- *
- * store: st{type}{size}{endian}_{access_type}(ptr, val)
- *
- * type is:
- * (empty): integer access
- * f : float access
- *
- * sign is:
- * (empty): for floats or 32 bit size
- * u : unsigned
- * s : signed
- *
- * size is:
- * b: 8 bits
- * w: 16 bits
- * l: 32 bits
- * q: 64 bits
- *
- * endian is:
- * (empty): target cpu endianness or 8 bit access
- * r : reversed target cpu endianness (not implemented yet)
- * be : big endian (not implemented yet)
- * le : little endian (not implemented yet)
- *
- * access_type is:
- * raw : host memory access
- * user : user mode access using soft MMU
- * kernel : kernel mode access using soft MMU
- */
-static inline int ldub_raw(void *ptr)
-{
- return *(uint8_t *)ptr;
-}
-
-static inline int ldsb_raw(void *ptr)
-{
- return *(int8_t *)ptr;
-}
-
-static inline void stb_raw(void *ptr, int v)
-{
- *(uint8_t *)ptr = v;
-}
-
-/* NOTE: on arm, putting 2 in /proc/sys/debug/alignment so that the
- kernel handles unaligned load/stores may give better results, but
- it is a system wide setting : bad */
-#if !defined(TARGET_WORDS_BIGENDIAN) && (defined(WORDS_BIGENDIAN) || defined(WORDS_ALIGNED))
-
-/* conservative code for little endian unaligned accesses */
-static inline int lduw_raw(void *ptr)
-{
-#ifdef __powerpc__
- int val;
- __asm__ __volatile__ ("lhbrx %0,0,%1" : "=r" (val) : "r" (ptr));
- return val;
-#else
- uint8_t *p = ptr;
- return p[0] | (p[1] << 8);
-#endif
-}
-
-static inline int ldsw_raw(void *ptr)
-{
-#ifdef __powerpc__
- int val;
- __asm__ __volatile__ ("lhbrx %0,0,%1" : "=r" (val) : "r" (ptr));
- return (int16_t)val;
-#else
- uint8_t *p = ptr;
- return (int16_t)(p[0] | (p[1] << 8));
-#endif
-}
-
-static inline int ldl_raw(void *ptr)
-{
-#ifdef __powerpc__
- int val;
- __asm__ __volatile__ ("lwbrx %0,0,%1" : "=r" (val) : "r" (ptr));
- return val;
-#else
- uint8_t *p = ptr;
- return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
-#endif
-}
-
-static inline uint64_t ldq_raw(void *ptr)
-{
- uint8_t *p = ptr;
- uint32_t v1, v2;
- v1 = ldl_raw(p);
- v2 = ldl_raw(p + 4);
- return v1 | ((uint64_t)v2 << 32);
-}
-
-static inline void stw_raw(void *ptr, int v)
-{
-#ifdef __powerpc__
- __asm__ __volatile__ ("sthbrx %1,0,%2" : "=m" (*(uint16_t *)ptr) : "r" (v), "r" (ptr));
-#else
- uint8_t *p = ptr;
- p[0] = v;
- p[1] = v >> 8;
-#endif
-}
-
-static inline void stl_raw(void *ptr, int v)
-{
-#ifdef __powerpc__
- __asm__ __volatile__ ("stwbrx %1,0,%2" : "=m" (*(uint32_t *)ptr) : "r" (v), "r" (ptr));
-#else
- uint8_t *p = ptr;
- p[0] = v;
- p[1] = v >> 8;
- p[2] = v >> 16;
- p[3] = v >> 24;
-#endif
-}
-
-static inline void stq_raw(void *ptr, uint64_t v)
-{
- uint8_t *p = ptr;
- stl_raw(p, (uint32_t)v);
- stl_raw(p + 4, v >> 32);
-}
-
-/* float access */
-
-static inline float ldfl_raw(void *ptr)
-{
- union {
- float f;
- uint32_t i;
- } u;
- u.i = ldl_raw(ptr);
- return u.f;
-}
-
-static inline void stfl_raw(void *ptr, float v)
-{
- union {
- float f;
- uint32_t i;
- } u;
- u.f = v;
- stl_raw(ptr, u.i);
-}
-
-static inline double ldfq_raw(void *ptr)
-{
- CPU_DoubleU u;
- u.l.lower = ldl_raw(ptr);
- u.l.upper = ldl_raw(ptr + 4);
- return u.d;
-}
-
-static inline void stfq_raw(void *ptr, double v)
-{
- CPU_DoubleU u;
- u.d = v;
- stl_raw(ptr, u.l.lower);
- stl_raw(ptr + 4, u.l.upper);
-}
-
-#elif defined(TARGET_WORDS_BIGENDIAN) && (!defined(WORDS_BIGENDIAN) || defined(WORDS_ALIGNED))
-
-static inline int lduw_raw(void *ptr)
-{
-#if defined(__i386__)
- int val;
- asm volatile ("movzwl %1, %0\n"
- "xchgb %b0, %h0\n"
- : "=q" (val)
- : "m" (*(uint16_t *)ptr));
- return val;
-#else
- uint8_t *b = (uint8_t *) ptr;
- return ((b[0] << 8) | b[1]);
-#endif
-}
-
-static inline int ldsw_raw(void *ptr)
-{
-#if defined(__i386__)
- int val;
- asm volatile ("movzwl %1, %0\n"
- "xchgb %b0, %h0\n"
- : "=q" (val)
- : "m" (*(uint16_t *)ptr));
- return (int16_t)val;
-#else
- uint8_t *b = (uint8_t *) ptr;
- return (int16_t)((b[0] << 8) | b[1]);
-#endif
-}
-
-static inline int ldl_raw(void *ptr)
-{
-#if defined(__i386__) || defined(__x86_64__)
- int val;
- asm volatile ("movl %1, %0\n"
- "bswap %0\n"
- : "=r" (val)
- : "m" (*(uint32_t *)ptr));
- return val;
-#else
- uint8_t *b = (uint8_t *) ptr;
- return (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | b[3];
-#endif
-}
-
-static inline uint64_t ldq_raw(void *ptr)
-{
- uint32_t a,b;
- a = ldl_raw(ptr);
- b = ldl_raw(ptr+4);
- return (((uint64_t)a<<32)|b);
-}
-
-static inline void stw_raw(void *ptr, int v)
-{
-#if defined(__i386__)
- asm volatile ("xchgb %b0, %h0\n"
- "movw %w0, %1\n"
- : "=q" (v)
- : "m" (*(uint16_t *)ptr), "0" (v));
-#else
- uint8_t *d = (uint8_t *) ptr;
- d[0] = v >> 8;
- d[1] = v;
-#endif
-}
-
-static inline void stl_raw(void *ptr, int v)
-{
-#if defined(__i386__) || defined(__x86_64__)
- asm volatile ("bswap %0\n"
- "movl %0, %1\n"
- : "=r" (v)
- : "m" (*(uint32_t *)ptr), "0" (v));
-#else
- uint8_t *d = (uint8_t *) ptr;
- d[0] = v >> 24;
- d[1] = v >> 16;
- d[2] = v >> 8;
- d[3] = v;
-#endif
-}
-
-static inline void stq_raw(void *ptr, uint64_t v)
-{
- stl_raw(ptr, v >> 32);
- stl_raw(ptr + 4, v);
-}
-
-/* float access */
-
-static inline float ldfl_raw(void *ptr)
-{
- union {
- float f;
- uint32_t i;
- } u;
- u.i = ldl_raw(ptr);
- return u.f;
-}
-
-static inline void stfl_raw(void *ptr, float v)
-{
- union {
- float f;
- uint32_t i;
- } u;
- u.f = v;
- stl_raw(ptr, u.i);
-}
-
-static inline double ldfq_raw(void *ptr)
-{
- CPU_DoubleU u;
- u.l.upper = ldl_raw(ptr);
- u.l.lower = ldl_raw(ptr + 4);
- return u.d;
-}
-
-static inline void stfq_raw(void *ptr, double v)
-{
- CPU_DoubleU u;
- u.d = v;
- stl_raw(ptr, u.l.upper);
- stl_raw(ptr + 4, u.l.lower);
-}
-
-#else
-
-static inline int lduw_raw(void *ptr)
-{
- return *(uint16_t *)ptr;
-}
-
-static inline int ldsw_raw(void *ptr)
-{
- return *(int16_t *)ptr;
-}
-
-static inline int ldl_raw(void *ptr)
-{
- return *(uint32_t *)ptr;
-}
-
-static inline uint64_t ldq_raw(void *ptr)
-{
- return *(uint64_t *)ptr;
-}
-
-static inline void stw_raw(void *ptr, int v)
-{
- *(uint16_t *)ptr = v;
-}
-
-static inline void stl_raw(void *ptr, int v)
-{
- *(uint32_t *)ptr = v;
-}
-
-static inline void stq_raw(void *ptr, uint64_t v)
-{
- *(uint64_t *)ptr = v;
-}
-
-/* float access */
-
-static inline float ldfl_raw(void *ptr)
-{
- return *(float *)ptr;
-}
-
-static inline double ldfq_raw(void *ptr)
-{
- return *(double *)ptr;
-}
-
-static inline void stfl_raw(void *ptr, float v)
-{
- *(float *)ptr = v;
-}
-
-static inline void stfq_raw(void *ptr, double v)
-{
- *(double *)ptr = v;
-}
-#endif
-
-/* MMU memory access macros */
-
-#if defined(CONFIG_USER_ONLY)
-
-/* if user mode, no other memory access functions */
-#define ldub(p) ldub_raw(p)
-#define ldsb(p) ldsb_raw(p)
-#define lduw(p) lduw_raw(p)
-#define ldsw(p) ldsw_raw(p)
-#define ldl(p) ldl_raw(p)
-#define ldq(p) ldq_raw(p)
-#define ldfl(p) ldfl_raw(p)
-#define ldfq(p) ldfq_raw(p)
-#define stb(p, v) stb_raw(p, v)
-#define stw(p, v) stw_raw(p, v)
-#define stl(p, v) stl_raw(p, v)
-#define stq(p, v) stq_raw(p, v)
-#define stfl(p, v) stfl_raw(p, v)
-#define stfq(p, v) stfq_raw(p, v)
-
-#define ldub_code(p) ldub_raw(p)
-#define ldsb_code(p) ldsb_raw(p)
-#define lduw_code(p) lduw_raw(p)
-#define ldsw_code(p) ldsw_raw(p)
-#define ldl_code(p) ldl_raw(p)
-
-#define ldub_kernel(p) ldub_raw(p)
-#define ldsb_kernel(p) ldsb_raw(p)
-#define lduw_kernel(p) lduw_raw(p)
-#define ldsw_kernel(p) ldsw_raw(p)
-#define ldl_kernel(p) ldl_raw(p)
-#define ldfl_kernel(p) ldfl_raw(p)
-#define ldfq_kernel(p) ldfq_raw(p)
-#define stb_kernel(p, v) stb_raw(p, v)
-#define stw_kernel(p, v) stw_raw(p, v)
-#define stl_kernel(p, v) stl_raw(p, v)
-#define stq_kernel(p, v) stq_raw(p, v)
-#define stfl_kernel(p, v) stfl_raw(p, v)
-#define stfq_kernel(p, vt) stfq_raw(p, v)
-
-#endif /* defined(CONFIG_USER_ONLY) */
-
-/* page related stuff */
-
-#define TARGET_PAGE_SIZE (1 << TARGET_PAGE_BITS)
-#define TARGET_PAGE_MASK ~(TARGET_PAGE_SIZE - 1)
-#define TARGET_PAGE_ALIGN(addr) (((addr) + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK)
-
-extern unsigned long qemu_real_host_page_size;
-extern unsigned long qemu_host_page_bits;
-extern unsigned long qemu_host_page_size;
-extern unsigned long qemu_host_page_mask;
-
-#define HOST_PAGE_ALIGN(addr) (((addr) + qemu_host_page_size - 1) & qemu_host_page_mask)
-
-/* same as PROT_xxx */
-#define PAGE_READ 0x0001
-#define PAGE_WRITE 0x0002
-#define PAGE_EXEC 0x0004
-#define PAGE_BITS (PAGE_READ | PAGE_WRITE | PAGE_EXEC)
-#define PAGE_VALID 0x0008
-/* original state of the write flag (used when tracking self-modifying
- code */
-#define PAGE_WRITE_ORG 0x0010
-
-void page_dump(FILE *f);
-int page_get_flags(unsigned long address);
-void page_set_flags(unsigned long start, unsigned long end, int flags);
-void page_unprotect_range(uint8_t *data, unsigned long data_size);
-
-#define CPUState CPUX86State
-
-void cpu_dump_state(CPUState *env, FILE *f,
- int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
- int flags);
-
-void cpu_abort(CPUState *env, const char *fmt, ...);
-extern CPUState *cpu_single_env;
-extern int code_copy_enabled;
-
-#define CPU_INTERRUPT_EXIT 0x01 /* wants exit from main loop */
-#define CPU_INTERRUPT_HARD 0x02 /* hardware interrupt pending */
-#define CPU_INTERRUPT_EXITTB 0x04 /* exit the current TB (use for x86 a20 case) */
-#define CPU_INTERRUPT_TIMER 0x08 /* internal timer exception pending */
-void cpu_interrupt(CPUState *s, int mask);
-void cpu_reset_interrupt(CPUState *env, int mask);
-
-int cpu_breakpoint_insert(CPUState *env, target_ulong pc);
-int cpu_breakpoint_remove(CPUState *env, target_ulong pc);
-void cpu_single_step(CPUState *env, int enabled);
-void cpu_reset(CPUState *s);
-CPUState *cpu_init(void);
-int main_loop(void);
-
-/* Return the physical page corresponding to a virtual one. Use it
- only for debugging because no protection checks are done. Return -1
- if no page found. */
-target_ulong cpu_get_phys_page_debug(CPUState *env, target_ulong addr);
-
-#define CPU_LOG_TB_OUT_ASM (1 << 0)
-#define CPU_LOG_TB_IN_ASM (1 << 1)
-#define CPU_LOG_TB_OP (1 << 2)
-#define CPU_LOG_TB_OP_OPT (1 << 3)
-#define CPU_LOG_INT (1 << 4)
-#define CPU_LOG_EXEC (1 << 5)
-#define CPU_LOG_PCALL (1 << 6)
-#define CPU_LOG_IOPORT (1 << 7)
-#define CPU_LOG_TB_CPU (1 << 8)
-
-/* define log items */
-typedef struct CPULogItem {
- int mask;
- const char *name;
- const char *help;
-} CPULogItem;
-
-extern CPULogItem cpu_log_items[];
-
-void cpu_set_log(int log_flags);
-void cpu_set_log_filename(const char *filename);
-int cpu_str_to_log_mask(const char *str);
-
-/* IO ports API */
-
-/* NOTE: as these functions may be even used when there is an isa
- brige on non x86 targets, we always defined them */
-#ifndef NO_CPU_IO_DEFS
-void cpu_outb(CPUState *env, int addr, int val);
-void cpu_outw(CPUState *env, int addr, int val);
-void cpu_outl(CPUState *env, int addr, int val);
-int cpu_inb(CPUState *env, int addr);
-int cpu_inw(CPUState *env, int addr);
-int cpu_inl(CPUState *env, int addr);
-#endif
-
-#if defined(__i386__) || defined(__x86_64__)
-static __inline__ void atomic_set_bit(long nr, volatile void *addr)
-{
- __asm__ __volatile__(
- "lock ; bts %1,%0"
- :"=m" (*(volatile long *)addr)
- :"dIr" (nr));
-}
-static __inline__ void atomic_clear_bit(long nr, volatile void *addr)
-{
- __asm__ __volatile__(
- "lock ; btr %1,%0"
- :"=m" (*(volatile long *)addr)
- :"dIr" (nr));
-}
-#elif defined(__ia64__)
-#include "ia64_intrinsic.h"
-#define atomic_set_bit(nr, addr) ({ \
- typeof(*addr) bit, old, new; \
- volatile typeof(*addr) *m; \
- \
- m = (volatile typeof(*addr)*)(addr + nr / (8*sizeof(*addr))); \
- bit = 1 << (nr % (8*sizeof(*addr))); \
- do { \
- old = *m; \
- new = old | bit; \
- } while (cmpxchg_acq(m, old, new) != old); \
-})
-
-#define atomic_clear_bit(nr, addr) ({ \
- typeof(*addr) bit, old, new; \
- volatile typeof(*addr) *m; \
- \
- m = (volatile typeof(*addr)*)(addr + nr / (8*sizeof(*addr))); \
- bit = ~(1 << (nr % (8*sizeof(*addr)))); \
- do { \
- old = *m; \
- new = old & bit; \
- } while (cmpxchg_acq(m, old, new) != old); \
-})
-#endif
-/* memory API */
-
-extern uint64_t phys_ram_size;
-extern int phys_ram_fd;
-extern uint8_t *phys_ram_base;
-extern uint8_t *phys_ram_dirty;
-
-/* physical memory access */
-#define IO_MEM_NB_ENTRIES 256
-#define TLB_INVALID_MASK (1 << 3)
-#define IO_MEM_SHIFT 4
-
-#define IO_MEM_RAM (0 << IO_MEM_SHIFT) /* hardcoded offset */
-#define IO_MEM_ROM (1 << IO_MEM_SHIFT) /* hardcoded offset */
-#define IO_MEM_UNASSIGNED (2 << IO_MEM_SHIFT)
-#define IO_MEM_CODE (3 << IO_MEM_SHIFT) /* used internally, never use directly */
-#define IO_MEM_NOTDIRTY (4 << IO_MEM_SHIFT) /* used internally, never use directly */
-
-typedef void CPUWriteMemoryFunc(void *opaque, target_phys_addr_t addr, uint32_t value);
-typedef uint32_t CPUReadMemoryFunc(void *opaque, target_phys_addr_t addr);
-
-void cpu_register_physical_memory(target_phys_addr_t start_addr,
- unsigned long size,
- unsigned long phys_offset);
-int cpu_register_io_memory(int io_index,
- CPUReadMemoryFunc **mem_read,
- CPUWriteMemoryFunc **mem_write,
- void *opaque);
-CPUWriteMemoryFunc **cpu_get_io_memory_write(int io_index);
-CPUReadMemoryFunc **cpu_get_io_memory_read(int io_index);
-
-void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf,
- int len, int is_write);
-static inline void cpu_physical_memory_read(target_phys_addr_t addr,
- uint8_t *buf, int len)
-{
- cpu_physical_memory_rw(addr, buf, len, 0);
-}
-static inline void cpu_physical_memory_write(target_phys_addr_t addr,
- const uint8_t *buf, int len)
-{
- cpu_physical_memory_rw(addr, (uint8_t *)buf, len, 1);
-}
-
-int cpu_memory_rw_debug(CPUState *env, target_ulong addr,
- uint8_t *buf, int len, int is_write);
-
-#define VGA_DIRTY_FLAG 0x01
-
-/* read dirty bit (return 0 or 1) */
-static inline int cpu_physical_memory_is_dirty(target_ulong addr)
-{
- return phys_ram_dirty[addr >> TARGET_PAGE_BITS];
-}
-
-static inline void cpu_physical_memory_set_dirty(target_ulong addr)
-{
- phys_ram_dirty[addr >> TARGET_PAGE_BITS] = 1;
-}
-
-void cpu_physical_memory_reset_dirty(target_ulong start, target_ulong end);
-
-#endif /* CPU_ALL_H */
+++ /dev/null
-/*
- * common defines for all CPUs
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#ifndef CPU_DEFS_H
-#define CPU_DEFS_H
-
-#include "config.h"
-#include <setjmp.h>
-#include <inttypes.h>
-#include "osdep.h"
-
-#ifndef TARGET_LONG_BITS
-#error TARGET_LONG_BITS must be defined before including this header
-#endif
-
-#if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__)
-#define HOST_LONG_BITS 64
-#else
-#define HOST_LONG_BITS 32
-#endif
-
-#ifndef TARGET_PHYS_ADDR_BITS
-#if TARGET_LONG_BITS >= HOST_LONG_BITS
-#define TARGET_PHYS_ADDR_BITS TARGET_LONG_BITS
-#else
-#define TARGET_PHYS_ADDR_BITS HOST_LONG_BITS
-#endif
-#endif
-
-#define TARGET_LONG_SIZE (TARGET_LONG_BITS / 8)
-
-/* target_ulong is the type of a virtual address */
-#if TARGET_LONG_SIZE == 4
-typedef int32_t target_long;
-typedef uint32_t target_ulong;
-#elif TARGET_LONG_SIZE == 8
-typedef int64_t target_long;
-typedef uint64_t target_ulong;
-#else
-#error TARGET_LONG_SIZE undefined
-#endif
-
-/* target_phys_addr_t is the type of a physical address (its size can
- be different from 'target_ulong'). We have sizeof(target_phys_addr)
- = max(sizeof(unsigned long),
- sizeof(size_of_target_physical_address)) because we must pass a
- host pointer to memory operations in some cases */
-
-#if TARGET_PHYS_ADDR_BITS == 32
-typedef uint32_t target_phys_addr_t;
-#elif TARGET_PHYS_ADDR_BITS == 64
-typedef uint64_t target_phys_addr_t;
-#else
-#error TARGET_PHYS_ADDR_BITS undefined
-#endif
-
-#define HOST_LONG_SIZE (HOST_LONG_BITS / 8)
-
-#define EXCP_INTERRUPT 256 /* async interruption */
-#define EXCP_HLT 257 /* hlt instruction reached */
-#define EXCP_DEBUG 258 /* cpu stopped after a breakpoint or singlestep */
-
-#define MAX_BREAKPOINTS 32
-
-#define CPU_TLB_SIZE 256
-
-typedef struct CPUTLBEntry {
- /* bit 31 to TARGET_PAGE_BITS : virtual address
- bit TARGET_PAGE_BITS-1..IO_MEM_SHIFT : if non zero, memory io
- zone number
- bit 3 : indicates that the entry is invalid
- bit 2..0 : zero
- */
- target_ulong address;
- /* addend to virtual address to get physical address */
- target_phys_addr_t addend;
-} CPUTLBEntry;
-
-#endif
+++ /dev/null
-/*
- * i386 virtual CPU header
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#ifndef CPU_I386_H
-#define CPU_I386_H
-
-#include "config.h"
-
-#ifdef TARGET_X86_64
-#define TARGET_LONG_BITS 64
-#else
-#define TARGET_LONG_BITS 32
-#endif
-
-/* target supports implicit self modifying code */
-#define TARGET_HAS_SMC
-/* support for self modifying code even if the modified instruction is
- close to the modifying instruction */
-#define TARGET_HAS_PRECISE_SMC
-
-#include "cpu-defs.h"
-
-#if defined(__i386__) && !defined(CONFIG_SOFTMMU)
-#define USE_CODE_COPY
-#endif
-
-/* Empty for now */
-typedef struct CPUX86State {
- uint32_t a20_mask;
- int interrupt_request;
- int send_event;
-} CPUX86State;
-
-#ifndef IN_OP_I386
-void cpu_x86_outb(CPUX86State *env, int addr, int val);
-void cpu_x86_outw(CPUX86State *env, int addr, int val);
-void cpu_x86_outl(CPUX86State *env, int addr, int val);
-int cpu_x86_inb(CPUX86State *env, int addr);
-int cpu_x86_inw(CPUX86State *env, int addr);
-int cpu_x86_inl(CPUX86State *env, int addr);
-#endif
-
-CPUX86State *cpu_x86_init(void);
-int cpu_x86_exec(CPUX86State *s);
-void cpu_x86_close(CPUX86State *s);
-int cpu_get_pic_interrupt(CPUX86State *s);
-/* MSDOS compatibility mode FPU exception support */
-void cpu_set_ferr(CPUX86State *s);
-
-/* helper2.c */
-void cpu_x86_set_a20(CPUX86State *env, int a20_state);
-
-#if defined(__i386__) || defined(__x86_64__)
-#define TARGET_PAGE_BITS 12
-#elif defined(__ia64__)
-#define TARGET_PAGE_BITS 14
-#endif
-#include "cpu-all.h"
-
-#endif /* CPU_I386_H */
+++ /dev/null
-#!/bin/sh
-
-# QEMU keysym adapter: create a header file to link the name to its keysym
-#
-# Copyright (c) 2004,2005 Johannes E. Schindelin
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to deal
-# in the Software without restriction, including without limitation the rights
-# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-# copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in
-# all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-# THE SOFTWARE.
-
-type="$1"
-cflags="$2"
-if [ -z "$cflags" ]; then
- echo "Usage: $0 vnc|sdl cflags"
- exit 1
-fi
-
-
-case "$type" in
-vnc)
- ignore_case=''
- header=rfb/keysym.h
- keysym_t=rfbKeySym
- pattern='^#define[ ]*XK_\([^ ]*\)[ ].*$'
- replacement='#ifdef XK_\1\n{\"\1\", XK_\1},\n#endif'
- extra_replace='cat'
- extra_sort='cat'
- ;;
-sdl)
- ignore_case='-f'
- header=SDL_keysym.h
- keysym_t=int
- pattern='^[ ]*SDLK_\([^ ]*\)[ ]*=.*$'
- replacement='{\"\1\", SDLK_\1},'
- extra_replace='sed -e s/{"\([RL]\)\(SUPER\|META\|ALT\|CONTROL\|SHIFT\)/{"\2_\1/ -e s/{"\([RL]\)CTRL/{"CONTROL_\1/ -e s/{"\(PAGE\)\(UP\|DOWN\)/{"\1_\2/ -e s/{"\(KP\)\([0-9]\)/{"\1_\2/ -e s/{"KP_MINUS/{"KP_SUBTRACT/ -e s/{"KP_PLUS/{"KP_ADD/ -e s/{"KP_PERIOD/{"KP_DECIMAL/ -e s/{"\(LEFT\|RIGHT\)\(PAREN\|BRACKET\)/{"\2\1/ -e s/{"EXCLAIM/{"EXCLAM/ -e s/{"\(CAPS\|NUM\)\(LOCK\)/{"\1_\2/ -e s/{"SCROLLOCK/{"SCROLL_LOCK/ -e s/{"KP_EQUALS/{"KP_EQUAL/ -e s/{"SYSREQ/{"SYS_REQ/ -e s/{"QUOTE"/{"APOSTROPHE"/ -e s/{"BACKQUOTE/{"GRAVE/ -e s/{"EQUALS/{"EQUAL/ -e s/{"EURO/{"EUROSIGN/ -e s/{"COMPOSE/{"MULTI_KEY/ -e s/{"MODE/{"MODE_SWITCH/ -e s/{"HASH/{"NUMBERSIGN/ -e s/{"WORLD_68/{"ADIAERESIS/ -e s/{"WORLD_86/{"ODIAERESIS/ -e s/{"WORLD_92/{"UDIAERESIS/ -e s/{"WORLD_63/{"SSHARP/ -e s/{"WORLD_20/{"ACUTE/ -e s/{"CARET/{"ASCIICIRCUM/'
- extra_sort='sort -f'
- ;;
-*) echo "Unknown type: $type is neither vnc nor sdl"; exit 1;;
-esac
-
-outfile=keysym_adapter_"$type".h
-
-echo "typedef struct {" > $outfile
-echo " const char* name;" >> $outfile
-echo " $keysym_t keysym;" >> $outfile
-echo "} name2keysym_t;" >> $outfile
-echo "static name2keysym_t name2keysym[]={" >> $outfile
-
-for path in $(echo "$cflags" | sed "s/-I/ /g"); do
- if [ -f $path/$header ]; then
- cat $path/$header
- fi
-done | tr "\011" " " | LC_ALL=C sort $ignore_case | uniq | \
-sed -n -e "s/$pattern/$replacement/p" | $extra_replace | \
-LC_ALL=C $extra_sort >> $outfile
-
-echo "{0,0}};" >> $outfile
-
-if [ -n "$ignore_case" ]; then
-echo "#define KEYBOARD_IGNORE_CASE" >> $outfile
-fi
-
-
+++ /dev/null
-/*
- * internal execution defines for qemu
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/* allow to see translation results - the slowdown should be negligible, so we leave it */
-#define DEBUG_DISAS
-
-#ifndef glue
-#define xglue(x, y) x ## y
-#define glue(x, y) xglue(x, y)
-#define stringify(s) tostring(s)
-#define tostring(s) #s
-#endif
-
-#if GCC_MAJOR < 3
-#define __builtin_expect(x, n) (x)
-#endif
-
-#ifdef __i386__
-#define REGPARM(n) __attribute((regparm(n)))
-#else
-#define REGPARM(n)
-#endif
-
-/* is_jmp field values */
-#define DISAS_NEXT 0 /* next instruction can be analyzed */
-#define DISAS_JUMP 1 /* only pc was modified dynamically */
-#define DISAS_UPDATE 2 /* cpu state was modified dynamically */
-#define DISAS_TB_JUMP 3 /* only pc was modified statically */
-
-struct TranslationBlock;
-
-/* XXX: make safe guess about sizes */
-#define MAX_OP_PER_INSTR 32
-#define OPC_BUF_SIZE 512
-#define OPC_MAX_SIZE (OPC_BUF_SIZE - MAX_OP_PER_INSTR)
-
-#define OPPARAM_BUF_SIZE (OPC_BUF_SIZE * 3)
-
-extern uint16_t gen_opc_buf[OPC_BUF_SIZE];
-extern uint32_t gen_opparam_buf[OPPARAM_BUF_SIZE];
-extern uint32_t gen_opc_pc[OPC_BUF_SIZE];
-extern uint32_t gen_opc_npc[OPC_BUF_SIZE];
-extern uint8_t gen_opc_cc_op[OPC_BUF_SIZE];
-extern uint8_t gen_opc_instr_start[OPC_BUF_SIZE];
-
-typedef void (GenOpFunc)(void);
-typedef void (GenOpFunc1)(long);
-typedef void (GenOpFunc2)(long, long);
-typedef void (GenOpFunc3)(long, long, long);
-
-#if defined(TARGET_I386)
-
-void optimize_flags_init(void);
-
-#endif
-
-extern FILE *logfile;
-extern int loglevel;
-
-int gen_intermediate_code(CPUState *env, struct TranslationBlock *tb);
-int gen_intermediate_code_pc(CPUState *env, struct TranslationBlock *tb);
-void dump_ops(const uint16_t *opc_buf, const uint32_t *opparam_buf);
-int cpu_gen_code(CPUState *env, struct TranslationBlock *tb,
- int max_code_size, int *gen_code_size_ptr);
-int cpu_restore_state(struct TranslationBlock *tb,
- CPUState *env, unsigned long searched_pc,
- void *puc);
-int cpu_gen_code_copy(CPUState *env, struct TranslationBlock *tb,
- int max_code_size, int *gen_code_size_ptr);
-int cpu_restore_state_copy(struct TranslationBlock *tb,
- CPUState *env, unsigned long searched_pc,
- void *puc);
-void cpu_resume_from_signal(CPUState *env1, void *puc);
-void cpu_exec_init(void);
-int page_unprotect(unsigned long address, unsigned long pc, void *puc);
-void tb_invalidate_phys_page_range(target_ulong start, target_ulong end,
- int is_cpu_write_access);
-void tb_invalidate_page_range(target_ulong start, target_ulong end);
-void tlb_flush_page(CPUState *env, target_ulong addr);
-void tlb_flush(CPUState *env, int flush_global);
-int tlb_set_page(CPUState *env, target_ulong vaddr,
- target_phys_addr_t paddr, int prot,
- int is_user, int is_softmmu);
-
-#define CODE_GEN_MAX_SIZE 65536
-#define CODE_GEN_ALIGN 16 /* must be >= of the size of a icache line */
-
-#define CODE_GEN_HASH_BITS 15
-#define CODE_GEN_HASH_SIZE (1 << CODE_GEN_HASH_BITS)
-
-#define CODE_GEN_PHYS_HASH_BITS 15
-#define CODE_GEN_PHYS_HASH_SIZE (1 << CODE_GEN_PHYS_HASH_BITS)
-
-/* maximum total translate dcode allocated */
-
-/* NOTE: the translated code area cannot be too big because on some
- archs the range of "fast" function calls is limited. Here is a
- summary of the ranges:
-
- i386 : signed 32 bits
- arm : signed 26 bits
- ppc : signed 24 bits
- sparc : signed 32 bits
- alpha : signed 23 bits
-*/
-
-#if defined(__alpha__)
-#define CODE_GEN_BUFFER_SIZE (2 * 1024 * 1024)
-#elif defined(__powerpc__)
-#define CODE_GEN_BUFFER_SIZE (6 * 1024 * 1024)
-#else
-#define CODE_GEN_BUFFER_SIZE (8 * 1024 * 1024)
-#endif
-
-//#define CODE_GEN_BUFFER_SIZE (128 * 1024)
-
-/* estimated block size for TB allocation */
-/* XXX: use a per code average code fragment size and modulate it
- according to the host CPU */
-#if defined(CONFIG_SOFTMMU)
-#define CODE_GEN_AVG_BLOCK_SIZE 128
-#else
-#define CODE_GEN_AVG_BLOCK_SIZE 64
-#endif
-
-#define CODE_GEN_MAX_BLOCKS (CODE_GEN_BUFFER_SIZE / CODE_GEN_AVG_BLOCK_SIZE)
-
-#if defined(__powerpc__)
-#define USE_DIRECT_JUMP
-#endif
-#if defined(__i386__) && !defined(_WIN32)
-#define USE_DIRECT_JUMP
-#endif
-
-typedef struct TranslationBlock {
- target_ulong pc; /* simulated PC corresponding to this block (EIP + CS base) */
- target_ulong cs_base; /* CS base for this block */
- unsigned int flags; /* flags defining in which context the code was generated */
- uint16_t size; /* size of target code for this block (1 <=
- size <= TARGET_PAGE_SIZE) */
- uint16_t cflags; /* compile flags */
-#define CF_CODE_COPY 0x0001 /* block was generated in code copy mode */
-#define CF_TB_FP_USED 0x0002 /* fp ops are used in the TB */
-#define CF_FP_USED 0x0004 /* fp ops are used in the TB or in a chained TB */
-#define CF_SINGLE_INSN 0x0008 /* compile only a single instruction */
-
- uint8_t *tc_ptr; /* pointer to the translated code */
- struct TranslationBlock *hash_next; /* next matching tb for virtual address */
- /* next matching tb for physical address. */
- struct TranslationBlock *phys_hash_next;
- /* first and second physical page containing code. The lower bit
- of the pointer tells the index in page_next[] */
- struct TranslationBlock *page_next[2];
- target_ulong page_addr[2];
-
- /* the following data are used to directly call another TB from
- the code of this one. */
- uint16_t tb_next_offset[2]; /* offset of original jump target */
-#ifdef USE_DIRECT_JUMP
- uint16_t tb_jmp_offset[4]; /* offset of jump instruction */
-#else
- uint32_t tb_next[2]; /* address of jump generated code */
-#endif
- /* list of TBs jumping to this one. This is a circular list using
- the two least significant bits of the pointers to tell what is
- the next pointer: 0 = jmp_next[0], 1 = jmp_next[1], 2 =
- jmp_first */
- struct TranslationBlock *jmp_next[2];
- struct TranslationBlock *jmp_first;
-} TranslationBlock;
-
-static inline unsigned int tb_hash_func(unsigned long pc)
-{
- return pc & (CODE_GEN_HASH_SIZE - 1);
-}
-
-static inline unsigned int tb_phys_hash_func(unsigned long pc)
-{
- return pc & (CODE_GEN_PHYS_HASH_SIZE - 1);
-}
-
-TranslationBlock *tb_alloc(unsigned long pc);
-void tb_flush(CPUState *env);
-void tb_link(TranslationBlock *tb);
-void tb_link_phys(TranslationBlock *tb,
- target_ulong phys_pc, target_ulong phys_page2);
-
-extern TranslationBlock *tb_hash[CODE_GEN_HASH_SIZE];
-extern TranslationBlock *tb_phys_hash[CODE_GEN_PHYS_HASH_SIZE];
-
-extern uint8_t code_gen_buffer[CODE_GEN_BUFFER_SIZE];
-extern uint8_t *code_gen_ptr;
-
-/* find a translation block in the translation cache. If not found,
- return NULL and the pointer to the last element of the list in pptb */
-static inline TranslationBlock *tb_find(TranslationBlock ***pptb,
- target_ulong pc,
- target_ulong cs_base,
- unsigned int flags)
-{
- TranslationBlock **ptb, *tb;
- unsigned int h;
-
- h = tb_hash_func(pc);
- ptb = &tb_hash[h];
- for(;;) {
- tb = *ptb;
- if (!tb)
- break;
- if (tb->pc == pc && tb->cs_base == cs_base && tb->flags == flags)
- return tb;
- ptb = &tb->hash_next;
- }
- *pptb = ptb;
- return NULL;
-}
-
-
-#if defined(USE_DIRECT_JUMP)
-
-#if defined(__powerpc__)
-static inline void tb_set_jmp_target1(unsigned long jmp_addr, unsigned long addr)
-{
- uint32_t val, *ptr;
-
- /* patch the branch destination */
- ptr = (uint32_t *)jmp_addr;
- val = *ptr;
- val = (val & ~0x03fffffc) | ((addr - jmp_addr) & 0x03fffffc);
- *ptr = val;
- /* flush icache */
- asm volatile ("dcbst 0,%0" : : "r"(ptr) : "memory");
- asm volatile ("sync" : : : "memory");
- asm volatile ("icbi 0,%0" : : "r"(ptr) : "memory");
- asm volatile ("sync" : : : "memory");
- asm volatile ("isync" : : : "memory");
-}
-#elif defined(__i386__)
-static inline void tb_set_jmp_target1(unsigned long jmp_addr, unsigned long addr)
-{
- /* patch the branch destination */
- *(uint32_t *)jmp_addr = addr - (jmp_addr + 4);
- /* no need to flush icache explicitely */
-}
-#endif
-
-static inline void tb_set_jmp_target(TranslationBlock *tb,
- int n, unsigned long addr)
-{
- unsigned long offset;
-
- offset = tb->tb_jmp_offset[n];
- tb_set_jmp_target1((unsigned long)(tb->tc_ptr + offset), addr);
- offset = tb->tb_jmp_offset[n + 2];
- if (offset != 0xffff)
- tb_set_jmp_target1((unsigned long)(tb->tc_ptr + offset), addr);
-}
-
-#else
-
-/* set the jump target */
-static inline void tb_set_jmp_target(TranslationBlock *tb,
- int n, unsigned long addr)
-{
- tb->tb_next[n] = addr;
-}
-
-#endif
-
-static inline void tb_add_jump(TranslationBlock *tb, int n,
- TranslationBlock *tb_next)
-{
- /* NOTE: this test is only needed for thread safety */
- if (!tb->jmp_next[n]) {
- /* patch the native jump address */
- tb_set_jmp_target(tb, n, (unsigned long)tb_next->tc_ptr);
-
- /* add in TB jmp circular list */
- tb->jmp_next[n] = tb_next->jmp_first;
- tb_next->jmp_first = (TranslationBlock *)((long)(tb) | (n));
- }
-}
-
-TranslationBlock *tb_find_pc(unsigned long pc_ptr);
-
-#ifndef offsetof
-#define offsetof(type, field) ((size_t) &((type *)0)->field)
-#endif
-
-#if defined(_WIN32)
-#define ASM_DATA_SECTION ".section \".data\"\n"
-#define ASM_PREVIOUS_SECTION ".section .text\n"
-#elif defined(__APPLE__)
-#define ASM_DATA_SECTION ".data\n"
-#define ASM_PREVIOUS_SECTION ".text\n"
-#define ASM_NAME(x) "_" #x
-#else
-#define ASM_DATA_SECTION ".section \".data\"\n"
-#define ASM_PREVIOUS_SECTION ".previous\n"
-#define ASM_NAME(x) stringify(x)
-#endif
-
-#if defined(__powerpc__)
-
-/* we patch the jump instruction directly */
-#define JUMP_TB(opname, tbparam, n, eip)\
-do {\
- asm volatile (ASM_DATA_SECTION\
- ASM_NAME(__op_label) #n "." ASM_NAME(opname) ":\n"\
- ".long 1f\n"\
- ASM_PREVIOUS_SECTION \
- "b " ASM_NAME(__op_jmp) #n "\n"\
- "1:\n");\
- T0 = (long)(tbparam) + (n);\
- EIP = eip;\
- EXIT_TB();\
-} while (0)
-
-#define JUMP_TB2(opname, tbparam, n)\
-do {\
- asm volatile ("b " ASM_NAME(__op_jmp) #n "\n");\
-} while (0)
-
-#elif defined(__i386__) && defined(USE_DIRECT_JUMP)
-
-/* we patch the jump instruction directly */
-#define JUMP_TB(opname, tbparam, n, eip)\
-do {\
- asm volatile (".section .data\n"\
- ASM_NAME(__op_label) #n "." ASM_NAME(opname) ":\n"\
- ".long 1f\n"\
- ASM_PREVIOUS_SECTION \
- "jmp " ASM_NAME(__op_jmp) #n "\n"\
- "1:\n");\
- T0 = (long)(tbparam) + (n);\
- EIP = eip;\
- EXIT_TB();\
-} while (0)
-
-#define JUMP_TB2(opname, tbparam, n)\
-do {\
- asm volatile ("jmp " ASM_NAME(__op_jmp) #n "\n");\
-} while (0)
-
-#else
-
-/* jump to next block operations (more portable code, does not need
- cache flushing, but slower because of indirect jump) */
-#define JUMP_TB(opname, tbparam, n, eip)\
-do {\
- static void __attribute__((unused)) *__op_label ## n = &&label ## n;\
- static void __attribute__((unused)) *dummy ## n = &&dummy_label ## n;\
- goto *(void *)(((TranslationBlock *)tbparam)->tb_next[n]);\
-label ## n:\
- T0 = (long)(tbparam) + (n);\
- EIP = eip;\
-dummy_label ## n:\
- EXIT_TB();\
-} while (0)
-
-/* second jump to same destination 'n' */
-#define JUMP_TB2(opname, tbparam, n)\
-do {\
- goto *(void *)(((TranslationBlock *)tbparam)->tb_next[n - 2]);\
-} while (0)
-
-#endif
-
-extern CPUWriteMemoryFunc *io_mem_write[IO_MEM_NB_ENTRIES][4];
-extern CPUReadMemoryFunc *io_mem_read[IO_MEM_NB_ENTRIES][4];
-extern void *io_mem_opaque[IO_MEM_NB_ENTRIES];
-
-#ifdef __powerpc__
-static inline int testandset (int *p)
-{
- int ret;
- __asm__ __volatile__ (
- "0: lwarx %0,0,%1\n"
- " xor. %0,%3,%0\n"
- " bne 1f\n"
- " stwcx. %2,0,%1\n"
- " bne- 0b\n"
- "1: "
- : "=&r" (ret)
- : "r" (p), "r" (1), "r" (0)
- : "cr0", "memory");
- return ret;
-}
-#endif
-
-#ifdef __i386__
-static inline int testandset (int *p)
-{
- char ret;
- long int readval;
-
- __asm__ __volatile__ ("lock; cmpxchgl %3, %1; sete %0"
- : "=q" (ret), "=m" (*p), "=a" (readval)
- : "r" (1), "m" (*p), "a" (0)
- : "memory");
- return ret;
-}
-#endif
-
-#ifdef __x86_64__
-static inline int testandset (int *p)
-{
- char ret;
- int readval;
-
- __asm__ __volatile__ ("lock; cmpxchgl %3, %1; sete %0"
- : "=q" (ret), "=m" (*p), "=a" (readval)
- : "r" (1), "m" (*p), "a" (0)
- : "memory");
- return ret;
-}
-#endif
-
-#ifdef __ia64__
-#include "ia64_intrinsic.h"
-static inline int testandset (int *p)
-{
- uint32_t o = 0, n = 1;
- return (int)cmpxchg_acq(p, o, n);
-}
-#endif
-
-#ifdef __s390__
-static inline int testandset (int *p)
-{
- int ret;
-
- __asm__ __volatile__ ("0: cs %0,%1,0(%2)\n"
- " jl 0b"
- : "=&d" (ret)
- : "r" (1), "a" (p), "0" (*p)
- : "cc", "memory" );
- return ret;
-}
-#endif
-
-#ifdef __alpha__
-static inline int testandset (int *p)
-{
- int ret;
- unsigned long one;
-
- __asm__ __volatile__ ("0: mov 1,%2\n"
- " ldl_l %0,%1\n"
- " stl_c %2,%1\n"
- " beq %2,1f\n"
- ".subsection 2\n"
- "1: br 0b\n"
- ".previous"
- : "=r" (ret), "=m" (*p), "=r" (one)
- : "m" (*p));
- return ret;
-}
-#endif
-
-#ifdef __sparc__
-static inline int testandset (int *p)
-{
- int ret;
-
- __asm__ __volatile__("ldstub [%1], %0"
- : "=r" (ret)
- : "r" (p)
- : "memory");
-
- return (ret ? 1 : 0);
-}
-#endif
-
-#ifdef __arm__
-static inline int testandset (int *spinlock)
-{
- register unsigned int ret;
- __asm__ __volatile__("swp %0, %1, [%2]"
- : "=r"(ret)
- : "0"(1), "r"(spinlock));
-
- return ret;
-}
-#endif
-
-#ifdef __mc68000
-static inline int testandset (int *p)
-{
- char ret;
- __asm__ __volatile__("tas %1; sne %0"
- : "=r" (ret)
- : "m" (p)
- : "cc","memory");
- return ret == 0;
-}
-#endif
-
-typedef int spinlock_t;
-
-#define SPIN_LOCK_UNLOCKED 0
-
-#if defined(CONFIG_USER_ONLY)
-static inline void spin_lock(spinlock_t *lock)
-{
- while (testandset(lock));
-}
-
-static inline void spin_unlock(spinlock_t *lock)
-{
- *lock = 0;
-}
-
-static inline int spin_trylock(spinlock_t *lock)
-{
- return !testandset(lock);
-}
-#else
-static inline void spin_lock(spinlock_t *lock)
-{
-}
-
-static inline void spin_unlock(spinlock_t *lock)
-{
-}
-
-static inline int spin_trylock(spinlock_t *lock)
-{
- return 1;
-}
-#endif
-
-extern spinlock_t tb_lock;
-
-extern int tb_invalidated_flag;
-
-#if !defined(CONFIG_USER_ONLY)
-
-void tlb_fill(unsigned long addr, int is_write, int is_user,
- void *retaddr);
-
-#define ACCESS_TYPE 3
-#define MEMSUFFIX _code
-#define env cpu_single_env
-
-#undef ACCESS_TYPE
-#undef MEMSUFFIX
-#undef env
-
-#endif
-
-#if defined(CONFIG_USER_ONLY)
-static inline target_ulong get_phys_addr_code(CPUState *env, target_ulong addr)
-{
- return addr;
-}
-#else
-/* NOTE: this function can trigger an exception */
-/* NOTE2: the returned address is not exactly the physical address: it
- is the offset relative to phys_ram_base */
-/* XXX: i386 target specific */
-static inline target_ulong get_phys_addr_code(CPUState *env, target_ulong addr)
-{
- return addr;
-}
-#endif
-
-//#define DEBUG_UNUSED_IOPORT
-//#define DEBUG_IOPORT
-#define TARGET_HVM
-
+++ /dev/null
-/*
- * virtual page mapping and translated block handling
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#include "config.h"
-#ifdef _WIN32
-#include <windows.h>
-#else
-#include <sys/types.h>
-#include <sys/mman.h>
-#endif
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <string.h>
-#include <errno.h>
-#include <unistd.h>
-#include <inttypes.h>
-
-#include "cpu.h"
-#include "exec-all.h"
-
-//#define DEBUG_TB_INVALIDATE
-//#define DEBUG_FLUSH
-//#define DEBUG_TLB
-
-/* make various TB consistency checks */
-//#define DEBUG_TB_CHECK
-//#define DEBUG_TLB_CHECK
-
-/* threshold to flush the translated code buffer */
-#define CODE_GEN_BUFFER_MAX_SIZE (CODE_GEN_BUFFER_SIZE - CODE_GEN_MAX_SIZE)
-
-#define SMC_BITMAP_USE_THRESHOLD 10
-
-#define MMAP_AREA_START 0x00000000
-#define MMAP_AREA_END 0xa8000000
-
-TranslationBlock tbs[CODE_GEN_MAX_BLOCKS];
-TranslationBlock *tb_hash[CODE_GEN_HASH_SIZE];
-TranslationBlock *tb_phys_hash[CODE_GEN_PHYS_HASH_SIZE];
-int nb_tbs;
-/* any access to the tbs or the page table must use this lock */
-spinlock_t tb_lock = SPIN_LOCK_UNLOCKED;
-
-uint8_t code_gen_buffer[CODE_GEN_BUFFER_SIZE];
-uint8_t *code_gen_ptr;
-
-uint64_t phys_ram_size;
-int phys_ram_fd;
-uint8_t *phys_ram_base;
-uint8_t *phys_ram_dirty;
-
-typedef struct PageDesc {
- /* list of TBs intersecting this ram page */
- TranslationBlock *first_tb;
- /* in order to optimize self modifying code, we count the number
- of lookups we do to a given page to use a bitmap */
- unsigned int code_write_count;
- uint8_t *code_bitmap;
-#if defined(CONFIG_USER_ONLY)
- unsigned long flags;
-#endif
-} PageDesc;
-
-typedef struct PhysPageDesc {
- /* offset in host memory of the page + io_index in the low 12 bits */
- unsigned long phys_offset;
-} PhysPageDesc;
-
-typedef struct VirtPageDesc {
- /* physical address of code page. It is valid only if 'valid_tag'
- matches 'virt_valid_tag' */
- target_ulong phys_addr;
- unsigned int valid_tag;
-#if !defined(CONFIG_SOFTMMU)
- /* original page access rights. It is valid only if 'valid_tag'
- matches 'virt_valid_tag' */
- unsigned int prot;
-#endif
-} VirtPageDesc;
-
-#define L2_BITS 10
-#define L1_BITS (32 - L2_BITS - TARGET_PAGE_BITS)
-
-#define L1_SIZE (1 << L1_BITS)
-#define L2_SIZE (1 << L2_BITS)
-
-unsigned long qemu_real_host_page_size;
-unsigned long qemu_host_page_bits;
-unsigned long qemu_host_page_size;
-unsigned long qemu_host_page_mask;
-
-/* io memory support */
-CPUWriteMemoryFunc *io_mem_write[IO_MEM_NB_ENTRIES][4];
-CPUReadMemoryFunc *io_mem_read[IO_MEM_NB_ENTRIES][4];
-void *io_mem_opaque[IO_MEM_NB_ENTRIES];
-static int io_mem_nb = 1;
-
-/* log support */
-char *logfilename = "/tmp/qemu.log";
-FILE *logfile;
-int loglevel;
-
-void cpu_exec_init(void)
-{
- /* alloc dirty bits array */
- phys_ram_dirty = qemu_malloc(phys_ram_size >> TARGET_PAGE_BITS);
-}
-
-/* enable or disable low levels log */
-void cpu_set_log(int log_flags)
-{
- loglevel = log_flags;
- if (!logfile) {
- logfile = fopen(logfilename, "w");
- if (!logfile) {
- perror(logfilename);
- _exit(1);
- }
-#if !defined(CONFIG_SOFTMMU)
- /* must avoid mmap() usage of glibc by setting a buffer "by hand" */
- {
- static uint8_t logfile_buf[4096];
- setvbuf(logfile, logfile_buf, _IOLBF, sizeof(logfile_buf));
- }
-#else
- setvbuf(logfile, NULL, _IOLBF, 0);
-#endif
-
- stdout = logfile;
- stderr = logfile;
- }
-}
-
-void cpu_set_log_filename(const char *filename)
-{
- logfilename = strdup(filename);
-}
-
-/* mask must never be zero, except for A20 change call */
-void cpu_interrupt(CPUState *env, int mask)
-{
- env->interrupt_request |= mask;
-}
-
-void cpu_reset_interrupt(CPUState *env, int mask)
-{
- env->interrupt_request &= ~mask;
-}
-
-CPULogItem cpu_log_items[] = {
- { CPU_LOG_TB_OUT_ASM, "out_asm",
- "show generated host assembly code for each compiled TB" },
- { CPU_LOG_TB_IN_ASM, "in_asm",
- "show target assembly code for each compiled TB" },
- { CPU_LOG_TB_OP, "op",
- "show micro ops for each compiled TB (only usable if 'in_asm' used)" },
-#ifdef TARGET_I386
- { CPU_LOG_TB_OP_OPT, "op_opt",
- "show micro ops after optimization for each compiled TB" },
-#endif
- { CPU_LOG_INT, "int",
- "show interrupts/exceptions in short format" },
- { CPU_LOG_EXEC, "exec",
- "show trace before each executed TB (lots of logs)" },
- { CPU_LOG_TB_CPU, "cpu",
- "show CPU state before bloc translation" },
-#ifdef TARGET_I386
- { CPU_LOG_PCALL, "pcall",
- "show protected mode far calls/returns/exceptions" },
-#endif
-#ifdef DEBUG_IOPORT
- { CPU_LOG_IOPORT, "ioport",
- "show all i/o ports accesses" },
-#endif
- { 0, NULL, NULL },
-};
-
-static int cmp1(const char *s1, int n, const char *s2)
-{
- if (strlen(s2) != n)
- return 0;
- return memcmp(s1, s2, n) == 0;
-}
-
-/* takes a comma separated list of log masks. Return 0 if error. */
-int cpu_str_to_log_mask(const char *str)
-{
- CPULogItem *item;
- int mask;
- const char *p, *p1;
-
- p = str;
- mask = 0;
- for(;;) {
- p1 = strchr(p, ',');
- if (!p1)
- p1 = p + strlen(p);
- if(cmp1(p,p1-p,"all")) {
- for(item = cpu_log_items; item->mask != 0; item++) {
- mask |= item->mask;
- }
- } else {
- for(item = cpu_log_items; item->mask != 0; item++) {
- if (cmp1(p, p1 - p, item->name))
- goto found;
- }
- return 0;
- }
- found:
- mask |= item->mask;
- if (*p1 != ',')
- break;
- p = p1 + 1;
- }
- return mask;
-}
-
-void cpu_abort(CPUState *env, const char *fmt, ...)
-{
- va_list ap;
-
- va_start(ap, fmt);
- fprintf(stderr, "qemu: fatal: ");
- vfprintf(stderr, fmt, ap);
- fprintf(stderr, "\n");
- va_end(ap);
- abort();
-}
-
-
-/* XXX: Simple implementation. Fix later */
-#define MAX_MMIO 32
-struct mmio_space {
- target_phys_addr_t start;
- unsigned long size;
- unsigned long io_index;
-} mmio[MAX_MMIO];
-unsigned long mmio_cnt;
-
-/* register physical memory. 'size' must be a multiple of the target
- page size. If (phys_offset & ~TARGET_PAGE_MASK) != 0, then it is an
- io memory page */
-void cpu_register_physical_memory(target_phys_addr_t start_addr,
- unsigned long size,
- unsigned long phys_offset)
-{
- int i;
-
- for (i = 0; i < mmio_cnt; i++) {
- if(mmio[i].start == start_addr) {
- mmio[i].io_index = phys_offset;
- mmio[i].size = size;
- return;
- }
- }
-
- if (mmio_cnt == MAX_MMIO) {
- fprintf(logfile, "too many mmio regions\n");
- exit(-1);
- }
-
- mmio[mmio_cnt].io_index = phys_offset;
- mmio[mmio_cnt].start = start_addr;
- mmio[mmio_cnt++].size = size;
-}
-
-/* mem_read and mem_write are arrays of functions containing the
- function to access byte (index 0), word (index 1) and dword (index
- 2). All functions must be supplied. If io_index is non zero, the
- corresponding io zone is modified. If it is zero, a new io zone is
- allocated. The return value can be used with
- cpu_register_physical_memory(). (-1) is returned if error. */
-int cpu_register_io_memory(int io_index,
- CPUReadMemoryFunc **mem_read,
- CPUWriteMemoryFunc **mem_write,
- void *opaque)
-{
- int i;
-
- if (io_index <= 0) {
- if (io_index >= IO_MEM_NB_ENTRIES)
- return -1;
- io_index = io_mem_nb++;
- } else {
- if (io_index >= IO_MEM_NB_ENTRIES)
- return -1;
- }
-
- for(i = 0;i < 3; i++) {
- io_mem_read[io_index][i] = mem_read[i];
- io_mem_write[io_index][i] = mem_write[i];
- }
- io_mem_opaque[io_index] = opaque;
- return io_index << IO_MEM_SHIFT;
-}
-
-CPUWriteMemoryFunc **cpu_get_io_memory_write(int io_index)
-{
- return io_mem_write[io_index >> IO_MEM_SHIFT];
-}
-
-CPUReadMemoryFunc **cpu_get_io_memory_read(int io_index)
-{
- return io_mem_read[io_index >> IO_MEM_SHIFT];
-}
-
-/* physical memory access (slow version, mainly for debug) */
-#if defined(CONFIG_USER_ONLY)
-void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf,
- int len, int is_write)
-{
- int l, flags;
- target_ulong page;
-
- while (len > 0) {
- page = addr & TARGET_PAGE_MASK;
- l = (page + TARGET_PAGE_SIZE) - addr;
- if (l > len)
- l = len;
- flags = page_get_flags(page);
- if (!(flags & PAGE_VALID))
- return;
- if (is_write) {
- if (!(flags & PAGE_WRITE))
- return;
- memcpy((uint8_t *)addr, buf, len);
- } else {
- if (!(flags & PAGE_READ))
- return;
- memcpy(buf, (uint8_t *)addr, len);
- }
- len -= l;
- buf += l;
- addr += l;
- }
-}
-#else
-
-int iomem_index(target_phys_addr_t addr)
-{
- int i;
-
- for (i = 0; i < mmio_cnt; i++) {
- unsigned long start, end;
-
- start = mmio[i].start;
- end = mmio[i].start + mmio[i].size;
-
- if ((addr >= start) && (addr <= end)){
- return (mmio[i].io_index >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
- }
- }
- return 0;
-}
-
-#ifdef __ia64__
-/* IA64 has seperate I/D cache, with coherence maintained by DMA controller.
- * So to emulate right behavior that guest OS is assumed, we need to flush
- * I/D cache here.
- */
-static void sync_icache(unsigned long address, int len)
-{
- int l;
- for(l = 0; l < (len + 32); l += 32)
- __ia64_fc(address + l);
-
- ia64_sync_i();
- ia64_srlz_i();
-}
-#endif
-
-void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf,
- int len, int is_write)
-{
- int l, io_index;
- uint8_t *ptr;
- uint32_t val;
- target_phys_addr_t page;
- unsigned long pd;
-
- while (len > 0) {
- page = addr & TARGET_PAGE_MASK;
- l = (page + TARGET_PAGE_SIZE) - addr;
- if (l > len)
- l = len;
-
- pd = page;
- io_index = iomem_index(page);
- if (is_write) {
- if (io_index) {
- if (l >= 4 && ((addr & 3) == 0)) {
- /* 32 bit read access */
- val = ldl_raw(buf);
- io_mem_write[io_index][2](io_mem_opaque[io_index], addr, val);
- l = 4;
- } else if (l >= 2 && ((addr & 1) == 0)) {
- /* 16 bit read access */
- val = lduw_raw(buf);
- io_mem_write[io_index][1](io_mem_opaque[io_index], addr, val);
- l = 2;
- } else {
- /* 8 bit access */
- val = ldub_raw(buf);
- io_mem_write[io_index][0](io_mem_opaque[io_index], addr, val);
- l = 1;
- }
- } else {
- unsigned long addr1;
-
- addr1 = (pd & TARGET_PAGE_MASK) + (addr & ~TARGET_PAGE_MASK);
- /* RAM case */
- ptr = phys_ram_base + addr1;
- memcpy(ptr, buf, l);
-#ifdef __ia64__
- sync_icache((unsigned long)ptr,l);
-#endif
- }
- } else {
- if (io_index) {
- if (l >= 4 && ((addr & 3) == 0)) {
- /* 32 bit read access */
- val = io_mem_read[io_index][2](io_mem_opaque[io_index], addr);
- stl_raw(buf, val);
- l = 4;
- } else if (l >= 2 && ((addr & 1) == 0)) {
- /* 16 bit read access */
- val = io_mem_read[io_index][1](io_mem_opaque[io_index], addr);
- stw_raw(buf, val);
- l = 2;
- } else {
- /* 8 bit access */
- val = io_mem_read[io_index][0](io_mem_opaque[io_index], addr);
- stb_raw(buf, val);
- l = 1;
- }
- } else {
- /* RAM case */
- ptr = phys_ram_base + (pd & TARGET_PAGE_MASK) +
- (addr & ~TARGET_PAGE_MASK);
- memcpy(buf, ptr, l);
- }
- }
- len -= l;
- buf += l;
- addr += l;
- }
-}
-#endif
-
-/* virtual memory access for debug */
-int cpu_memory_rw_debug(CPUState *env, target_ulong addr,
- uint8_t *buf, int len, int is_write)
-{
- int l;
- target_ulong page, phys_addr;
-
- while (len > 0) {
- page = addr & TARGET_PAGE_MASK;
- phys_addr = cpu_get_phys_page_debug(env, page);
- /* if no physical page mapped, return an error */
- if (phys_addr == -1)
- return -1;
- l = (page + TARGET_PAGE_SIZE) - addr;
- if (l > len)
- l = len;
- cpu_physical_memory_rw(phys_addr + (addr & ~TARGET_PAGE_MASK),
- buf, l, is_write);
- len -= l;
- buf += l;
- addr += l;
- }
- return 0;
-}
-
-void cpu_physical_memory_reset_dirty(target_ulong start, target_ulong end)
-{
- uint8_t *p;
- int len;
-
- if ((len = (end - start)) <= 0)
- return;
- p = phys_ram_dirty + (start >> TARGET_PAGE_BITS);
- len = len >> TARGET_PAGE_BITS;
- while (len > 0)
- p[--len] &= ~VGA_DIRTY_FLAG;
- return;
-}
+++ /dev/null
-/*
- * ACPI emulation
- *
- * Copyright (c) 2006 Virtual Iron Software
- *
- * This module provides the beginnings of some ACPI emulation.
- * Initially, this code handles writes to the sleep state
- * registers. This is done to detect requests to power-off
- * a guest domain.
- *
- * Later, and driven by empirical evidence, additional capabilities
- * and emulation might be added.
- *
- * Currently, the FADT specifies a small register set, of which
- * only PM1_CNTa is available. In addition, the ASL code specifies
- * the proper values to write on an S5 (poweroff) request, which
- * this code understands.
- *
- */
-
-#include "vl.h"
-extern FILE* logfile;
-
-// Define some basic offsets to ACPI registers
-
-//#define DEBUG_ACPI
-#define PM1a_STS 0x0
-#define PM1a_EN 0x1
-#define PM1b_STS 0x2
-#define PM1b_EN 0x3
-#define PM1_CNTa 0x4
-#define PM1_CNTb 0x6
-
-// Values within PM1_CNTa that we need for power handling
-
-#define SLP_TYP_MASK 0x1C00
-#define SLP_VAL 0x1C00
-#define SLP_EN 0x2000
-
-// Base ACPI register address
-
-static unsigned int acpi_base = 0;
-
-/* acpi_write_byte - handle byte writes for ACPI I/O region
- *
- * Input:
- * opaque pointer to private data structure (currently NULL)
- * addr I/O space address to be written
- * data data to be written
- *
- * Output:
- * none
- *
- * Returns:
- * none
- */
-
-static void acpi_write_byte(void *opaque, uint32_t addr, uint32_t data) {
-
-#ifdef DEBUG_ACPI
- fprintf(logfile, "%s - addr 0x%x, data 0x%x\n", __FUNCTION__, addr, data);
-#endif
-
- // All byte writes are currently ignored
-
- return;
-}
-
-/* acpi_write_word - handle word writes for ACPI I/O region
- *
- * Input:
- * opaque pointer to private data structure (currently NULL)
- * addr I/O space address to be written
- * data data to be written
- *
- * Output:
- * none
- *
- * Returns:
- * none
- */
-
-static void acpi_write_word(void *opaque, uint32_t addr, uint32_t data) {
-
-#ifdef DEBUG_ACPI
- fprintf(logfile, "%s - addr 0x%x, data 0x%x\n", __FUNCTION__, addr, data);
-#endif
-
- // Only a write to PM1_CNTa for power operations is handled
- // All others are ignored
-
- if (addr == acpi_base + PM1_CNTa) {
- if ( ( (data & SLP_EN) != 0) &&
- ( (data & SLP_TYP_MASK) == SLP_VAL) ) {
- qemu_system_shutdown_request();
- fprintf(logfile, "%s - ACPI Power State 5 (poweroff) requested\n", __FUNCTION__);
- }
- }
-
- return;
-}
-
-/* acpi_read_byte - handle byte reads for ACPI I/O region
- *
- * Input:
- * opaque pointer to private data structure (currently NULL)
- * addr I/O space address to be written
- *
- * Output:
- * none
- *
- * Returns:
- * data read
- */
-
-static uint32_t acpi_read_byte(void *opaque, uint32_t addr) {
-
-#ifdef DEBUG_ACPI
- fprintf(logfile, "%s - addr 0x%x\n", __FUNCTION__, addr);
-#endif
-
- // All reads return 0
-
- return 0;
-}
-
-/* acpi_read_word - handle word reads for ACPI I/O region
- *
- * Input:
- * opaque pointer to private data structure (currently NULL)
- * addr I/O space address to be written
- *
- * Output:
- * none
- *
- * Returns:
- * data read
- */
-
-static uint32_t acpi_read_word(void *opaque, uint32_t addr) {
-
-#ifdef DEBUG_ACPI
- fprintf(logfile, "%s - addr 0x%x\n", __FUNCTION__, addr);
-#endif
-
- // All reads return 0
-
- return 0;
-}
-
-/* acpi_init - initialize for ACPI I/O space operation handling
- *
- * Input:
- * base base I/O address
- *
- * Output:
- * none
- *
- * Returns:
- * status
- */
-
-int acpi_init(unsigned int base) {
-
- fprintf(logfile, "%s - registering ACPI addresses at 0x%x\n", __FUNCTION__, base);
-
- // Map 16 bytes of reads/writes for bytes/words
-
- register_ioport_write(base, 16, sizeof(unsigned char), acpi_write_byte, NULL);
- register_ioport_read(base, 16, sizeof(unsigned char), acpi_read_byte, NULL);
-
- register_ioport_write(base, 16, sizeof(unsigned short), acpi_write_word, NULL);
- register_ioport_read(base, 16, sizeof(unsigned short), acpi_read_word, NULL);
-
- acpi_base = base;
-
- return 0;
-}
+++ /dev/null
-/*
- * QEMU ADB support
- *
- * Copyright (c) 2004 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "vl.h"
-
-/* ADB commands */
-#define ADB_BUSRESET 0x00
-#define ADB_FLUSH 0x01
-#define ADB_WRITEREG 0x08
-#define ADB_READREG 0x0c
-
-/* ADB device commands */
-#define ADB_CMD_SELF_TEST 0xff
-#define ADB_CMD_CHANGE_ID 0xfe
-#define ADB_CMD_CHANGE_ID_AND_ACT 0xfd
-#define ADB_CMD_CHANGE_ID_AND_ENABLE 0x00
-
-/* ADB default device IDs (upper 4 bits of ADB command byte) */
-#define ADB_DONGLE 1
-#define ADB_KEYBOARD 2
-#define ADB_MOUSE 3
-#define ADB_TABLET 4
-#define ADB_MODEM 5
-#define ADB_MISC 7
-
-/* error codes */
-#define ADB_RET_NOTPRESENT (-2)
-
-int adb_request(ADBBusState *s, uint8_t *obuf, const uint8_t *buf, int len)
-{
- ADBDevice *d;
- int devaddr, cmd, i;
-
- cmd = buf[0] & 0xf;
- if (cmd == ADB_BUSRESET) {
- for(i = 0; i < s->nb_devices; i++) {
- d = &s->devices[i];
- if (d->devreset) {
- d->devreset(d);
- }
- }
- return 0;
- }
- devaddr = buf[0] >> 4;
- for(i = 0; i < s->nb_devices; i++) {
- d = &s->devices[i];
- if (d->devaddr == devaddr) {
- return d->devreq(d, obuf, buf, len);
- }
- }
- return ADB_RET_NOTPRESENT;
-}
-
-/* XXX: move that to cuda ? */
-int adb_poll(ADBBusState *s, uint8_t *obuf)
-{
- ADBDevice *d;
- int olen, i;
- uint8_t buf[1];
-
- olen = 0;
- for(i = 0; i < s->nb_devices; i++) {
- if (s->poll_index >= s->nb_devices)
- s->poll_index = 0;
- d = &s->devices[s->poll_index];
- buf[0] = ADB_READREG | (d->devaddr << 4);
- olen = adb_request(s, obuf + 1, buf, 1);
- /* if there is data, we poll again the same device */
- if (olen > 0) {
- obuf[0] = buf[0];
- olen++;
- break;
- }
- s->poll_index++;
- }
- return olen;
-}
-
-ADBDevice *adb_register_device(ADBBusState *s, int devaddr,
- ADBDeviceRequest *devreq,
- ADBDeviceReset *devreset,
- void *opaque)
-{
- ADBDevice *d;
- if (s->nb_devices >= MAX_ADB_DEVICES)
- return NULL;
- d = &s->devices[s->nb_devices++];
- d->bus = s;
- d->devaddr = devaddr;
- d->devreq = devreq;
- d->devreset = devreset;
- d->opaque = opaque;
- return d;
-}
-
-/***************************************************************/
-/* Keyboard ADB device */
-
-typedef struct KBDState {
- uint8_t data[128];
- int rptr, wptr, count;
-} KBDState;
-
-static const uint8_t pc_to_adb_keycode[256] = {
- 0, 53, 18, 19, 20, 21, 23, 22, 26, 28, 25, 29, 27, 24, 51, 48,
- 12, 13, 14, 15, 17, 16, 32, 34, 31, 35, 33, 30, 36, 54, 0, 1,
- 2, 3, 5, 4, 38, 40, 37, 41, 39, 50, 56, 42, 6, 7, 8, 9,
- 11, 45, 46, 43, 47, 44,123, 67, 58, 49, 57,122,120, 99,118, 96,
- 97, 98,100,101,109, 71,107, 89, 91, 92, 78, 86, 87, 88, 69, 83,
- 84, 85, 82, 65, 0, 0, 10,103,111, 0, 0,110, 81, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 94, 0, 93, 0, 0, 0, 0, 0, 0,104,102, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 76,125, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,105, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 75, 0, 0,124, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0,115, 62,116, 0, 59, 0, 60, 0,119,
- 61,121,114,117, 0, 0, 0, 0, 0, 0, 0, 55,126, 0,127, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-};
-
-static void adb_kbd_put_keycode(void *opaque, int keycode)
-{
- ADBDevice *d = opaque;
- KBDState *s = d->opaque;
-
- if (s->count < sizeof(s->data)) {
- s->data[s->wptr] = keycode;
- if (++s->wptr == sizeof(s->data))
- s->wptr = 0;
- s->count++;
- }
-}
-
-static int adb_kbd_poll(ADBDevice *d, uint8_t *obuf)
-{
- static int ext_keycode;
- KBDState *s = d->opaque;
- int adb_keycode, keycode;
- int olen;
-
- olen = 0;
- for(;;) {
- if (s->count == 0)
- break;
- keycode = s->data[s->rptr];
- if (++s->rptr == sizeof(s->data))
- s->rptr = 0;
- s->count--;
-
- if (keycode == 0xe0) {
- ext_keycode = 1;
- } else {
- if (ext_keycode)
- adb_keycode = pc_to_adb_keycode[keycode | 0x80];
- else
- adb_keycode = pc_to_adb_keycode[keycode & 0x7f];
- obuf[0] = adb_keycode | (keycode & 0x80);
- /* NOTE: could put a second keycode if needed */
- obuf[1] = 0xff;
- olen = 2;
- ext_keycode = 0;
- break;
- }
- }
- return olen;
-}
-
-static int adb_kbd_request(ADBDevice *d, uint8_t *obuf,
- const uint8_t *buf, int len)
-{
- KBDState *s = d->opaque;
- int cmd, reg, olen;
-
- if ((buf[0] & 0x0f) == ADB_FLUSH) {
- /* flush keyboard fifo */
- s->wptr = s->rptr = s->count = 0;
- return 0;
- }
-
- cmd = buf[0] & 0xc;
- reg = buf[0] & 0x3;
- olen = 0;
- switch(cmd) {
- case ADB_WRITEREG:
- switch(reg) {
- case 2:
- /* LED status */
- break;
- case 3:
- switch(buf[2]) {
- case ADB_CMD_SELF_TEST:
- break;
- case ADB_CMD_CHANGE_ID:
- case ADB_CMD_CHANGE_ID_AND_ACT:
- case ADB_CMD_CHANGE_ID_AND_ENABLE:
- d->devaddr = buf[1] & 0xf;
- break;
- default:
- /* XXX: check this */
- d->devaddr = buf[1] & 0xf;
- d->handler = buf[2];
- break;
- }
- }
- break;
- case ADB_READREG:
- switch(reg) {
- case 0:
- olen = adb_kbd_poll(d, obuf);
- break;
- case 1:
- break;
- case 2:
- obuf[0] = 0x00; /* XXX: check this */
- obuf[1] = 0x07; /* led status */
- olen = 2;
- break;
- case 3:
- obuf[0] = d->handler;
- obuf[1] = d->devaddr;
- olen = 2;
- break;
- }
- break;
- }
- return olen;
-}
-
-void adb_kbd_init(ADBBusState *bus)
-{
- ADBDevice *d;
- KBDState *s;
- s = qemu_mallocz(sizeof(KBDState));
- d = adb_register_device(bus, ADB_KEYBOARD, adb_kbd_request, NULL, s);
- d->handler = 1;
- qemu_add_kbd_event_handler(adb_kbd_put_keycode, d);
-}
-
-/***************************************************************/
-/* Mouse ADB device */
-
-typedef struct MouseState {
- int buttons_state, last_buttons_state;
- int dx, dy, dz;
-} MouseState;
-
-static void adb_mouse_event(void *opaque,
- int dx1, int dy1, int dz1, int buttons_state)
-{
- ADBDevice *d = opaque;
- MouseState *s = d->opaque;
-
- s->dx += dx1;
- s->dy += dy1;
- s->dz += dz1;
- s->buttons_state = buttons_state;
-}
-
-
-static int adb_mouse_poll(ADBDevice *d, uint8_t *obuf)
-{
- MouseState *s = d->opaque;
- int dx, dy;
-
- if (s->last_buttons_state == s->buttons_state &&
- s->dx == 0 && s->dy == 0)
- return 0;
-
- dx = s->dx;
- if (dx < -63)
- dx = -63;
- else if (dx > 63)
- dx = 63;
-
- dy = s->dy;
- if (dy < -63)
- dy = -63;
- else if (dy > 63)
- dy = 63;
-
- s->dx -= dx;
- s->dy -= dy;
- s->last_buttons_state = s->buttons_state;
-
- dx &= 0x7f;
- dy &= 0x7f;
-
- if (!(s->buttons_state & MOUSE_EVENT_LBUTTON))
- dy |= 0x80;
- if (!(s->buttons_state & MOUSE_EVENT_RBUTTON))
- dx |= 0x80;
-
- obuf[0] = dy;
- obuf[1] = dx;
- return 2;
-}
-
-static int adb_mouse_request(ADBDevice *d, uint8_t *obuf,
- const uint8_t *buf, int len)
-{
- MouseState *s = d->opaque;
- int cmd, reg, olen;
-
- if ((buf[0] & 0x0f) == ADB_FLUSH) {
- /* flush mouse fifo */
- s->buttons_state = s->last_buttons_state;
- s->dx = 0;
- s->dy = 0;
- s->dz = 0;
- return 0;
- }
-
- cmd = buf[0] & 0xc;
- reg = buf[0] & 0x3;
- olen = 0;
- switch(cmd) {
- case ADB_WRITEREG:
- switch(reg) {
- case 2:
- break;
- case 3:
- switch(buf[2]) {
- case ADB_CMD_SELF_TEST:
- break;
- case ADB_CMD_CHANGE_ID:
- case ADB_CMD_CHANGE_ID_AND_ACT:
- case ADB_CMD_CHANGE_ID_AND_ENABLE:
- d->devaddr = buf[1] & 0xf;
- break;
- default:
- /* XXX: check this */
- d->devaddr = buf[1] & 0xf;
- break;
- }
- }
- break;
- case ADB_READREG:
- switch(reg) {
- case 0:
- olen = adb_mouse_poll(d, obuf);
- break;
- case 1:
- break;
- case 3:
- obuf[0] = d->handler;
- obuf[1] = d->devaddr;
- olen = 2;
- break;
- }
- break;
- }
- return olen;
-}
-
-void adb_mouse_init(ADBBusState *bus)
-{
- ADBDevice *d;
- MouseState *s;
-
- s = qemu_mallocz(sizeof(MouseState));
- d = adb_register_device(bus, ADB_MOUSE, adb_mouse_request, NULL, s);
- d->handler = 2;
- qemu_add_mouse_event_handler(adb_mouse_event, d);
-}
+++ /dev/null
-/*
- * QEMU Adlib emulation
- *
- * Copyright (c) 2004 Vassili Karpov (malc)
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "vl.h"
-
-#define dolog(...) AUD_log ("adlib", __VA_ARGS__)
-#ifdef DEBUG
-#define ldebug(...) dolog (__VA_ARGS__)
-#else
-#define ldebug(...)
-#endif
-
-#ifdef USE_YMF262
-#define HAS_YMF262 1
-#include "ymf262.h"
-void YMF262UpdateOneQEMU(int which, INT16 *dst, int length);
-#define SHIFT 2
-#else
-#include "fmopl.h"
-#define SHIFT 1
-#endif
-
-#ifdef _WIN32
-#include <windows.h>
-#define small_delay() Sleep (1)
-#else
-#define small_delay() usleep (1)
-#endif
-
-#define IO_READ_PROTO(name) \
- uint32_t name (void *opaque, uint32_t nport)
-#define IO_WRITE_PROTO(name) \
- void name (void *opaque, uint32_t nport, uint32_t val)
-
-static struct {
- int port;
- int freq;
-} conf = {0x220, 44100};
-
-typedef struct {
- int enabled;
- int active;
- int cparam;
- int64_t ticks;
- int bufpos;
- int16_t *mixbuf;
- double interval;
- QEMUTimer *ts, *opl_ts;
- SWVoice *voice;
- int left, pos, samples, bytes_per_second, old_free;
- int refcount;
-#ifndef USE_YMF262
- FM_OPL *opl;
-#endif
-} AdlibState;
-
-static AdlibState adlib;
-
-static IO_WRITE_PROTO(adlib_write)
-{
- AdlibState *s = opaque;
- int a = nport & 3;
- int status;
-
- s->ticks = qemu_get_clock (vm_clock);
- s->active = 1;
- AUD_enable (s->voice, 1);
-
-#ifdef USE_YMF262
- status = YMF262Write (0, a, val);
-#else
- status = OPLWrite (s->opl, a, val);
-#endif
-}
-
-static IO_READ_PROTO(adlib_read)
-{
- AdlibState *s = opaque;
- uint8_t data;
- int a = nport & 3;
-
-#ifdef USE_YMF262
- (void) s;
- data = YMF262Read (0, a);
-#else
- data = OPLRead (s->opl, a);
-#endif
- return data;
-}
-
-static void OPL_timer (void *opaque)
-{
- AdlibState *s = opaque;
-#ifdef USE_YMF262
- YMF262TimerOver (s->cparam >> 1, s->cparam & 1);
-#else
- OPLTimerOver (s->opl, s->cparam);
-#endif
- qemu_mod_timer (s->opl_ts, qemu_get_clock (vm_clock) + s->interval);
-}
-
-static void YMF262TimerHandler (int c, double interval_Sec)
-{
- AdlibState *s = &adlib;
- if (interval_Sec == 0.0) {
- qemu_del_timer (s->opl_ts);
- return;
- }
- s->cparam = c;
- s->interval = ticks_per_sec * interval_Sec;
- qemu_mod_timer (s->opl_ts, qemu_get_clock (vm_clock) + s->interval);
- small_delay ();
-}
-
-static int write_audio (AdlibState *s, int samples)
-{
- int net = 0;
- int ss = samples;
- while (samples) {
- int nbytes = samples << SHIFT;
- int wbytes = AUD_write (s->voice,
- s->mixbuf + (s->pos << (SHIFT - 1)),
- nbytes);
- int wsampl = wbytes >> SHIFT;
- samples -= wsampl;
- s->pos = (s->pos + wsampl) % s->samples;
- net += wsampl;
- if (!wbytes)
- break;
- }
- if (net > ss) {
- dolog ("WARNING: net > ss\n");
- }
- return net;
-}
-
-static void timer (void *opaque)
-{
- AdlibState *s = opaque;
- int elapsed, samples, net = 0;
-
- if (s->refcount)
- dolog ("refcount=%d\n", s->refcount);
-
- s->refcount += 1;
- if (!(s->active && s->enabled))
- goto reset;
-
- AUD_run ();
-
- while (s->left) {
- int written = write_audio (s, s->left);
- net += written;
- if (!written)
- goto reset2;
- s->left -= written;
- }
- s->pos = 0;
-
- elapsed = AUD_calc_elapsed (s->voice);
- if (!elapsed)
- goto reset2;
-
- /* elapsed = AUD_get_free (s->voice); */
- samples = elapsed >> SHIFT;
- if (!samples)
- goto reset2;
-
- samples = audio_MIN (samples, s->samples - s->pos);
- if (s->left)
- dolog ("left=%d samples=%d elapsed=%d free=%d\n",
- s->left, samples, elapsed, AUD_get_free (s->voice));
-
- if (!samples)
- goto reset2;
-
-#ifdef USE_YMF262
- YMF262UpdateOneQEMU (0, s->mixbuf + s->pos * 2, samples);
-#else
- YM3812UpdateOne (s->opl, s->mixbuf + s->pos, samples);
-#endif
-
- while (samples) {
- int written = write_audio (s, samples);
- net += written;
- if (!written)
- break;
- samples -= written;
- }
- if (!samples)
- s->pos = 0;
- s->left = samples;
-
-reset2:
- AUD_adjust (s->voice, net << SHIFT);
-reset:
- qemu_mod_timer (s->ts, qemu_get_clock (vm_clock) + ticks_per_sec / 1024);
- s->refcount -= 1;
-}
-
-static void Adlib_fini (AdlibState *s)
-{
-#ifdef USE_YMF262
- YMF262Shutdown ();
-#else
- if (s->opl) {
- OPLDestroy (s->opl);
- s->opl = NULL;
- }
-#endif
-
- if (s->opl_ts)
- qemu_free_timer (s->opl_ts);
-
- if (s->ts)
- qemu_free_timer (s->ts);
-
-#define maybe_free(p) if (p) qemu_free (p)
- maybe_free (s->mixbuf);
-#undef maybe_free
-
- s->active = 0;
- s->enabled = 0;
-}
-
-void Adlib_init (void)
-{
- AdlibState *s = &adlib;
-
- memset (s, 0, sizeof (*s));
-
-#ifdef USE_YMF262
- if (YMF262Init (1, 14318180, conf.freq)) {
- dolog ("YMF262Init %d failed\n", conf.freq);
- return;
- }
- else {
- YMF262SetTimerHandler (0, YMF262TimerHandler, 0);
- s->enabled = 1;
- }
-#else
- s->opl = OPLCreate (OPL_TYPE_YM3812, 3579545, conf.freq);
- if (!s->opl) {
- dolog ("OPLCreate %d failed\n", conf.freq);
- return;
- }
- else {
- OPLSetTimerHandler (s->opl, YMF262TimerHandler, 0);
- s->enabled = 1;
- }
-#endif
-
- s->opl_ts = qemu_new_timer (vm_clock, OPL_timer, s);
- if (!s->opl_ts) {
- dolog ("Can not get timer for adlib emulation\n");
- Adlib_fini (s);
- return;
- }
-
- s->ts = qemu_new_timer (vm_clock, timer, s);
- if (!s->opl_ts) {
- dolog ("Can not get timer for adlib emulation\n");
- Adlib_fini (s);
- return;
- }
-
- s->voice = AUD_open (s->voice, "adlib", conf.freq, SHIFT, AUD_FMT_S16);
- if (!s->voice) {
- Adlib_fini (s);
- return;
- }
-
- s->bytes_per_second = conf.freq << SHIFT;
- s->samples = AUD_get_buffer_size (s->voice) >> SHIFT;
- s->mixbuf = qemu_mallocz (s->samples << SHIFT);
-
- if (!s->mixbuf) {
- dolog ("not enough memory for adlib mixing buffer (%d)\n",
- s->samples << SHIFT);
- Adlib_fini (s);
- return;
- }
- register_ioport_read (0x388, 4, 1, adlib_read, s);
- register_ioport_write (0x388, 4, 1, adlib_write, s);
-
- register_ioport_read (conf.port, 4, 1, adlib_read, s);
- register_ioport_write (conf.port, 4, 1, adlib_write, s);
-
- register_ioport_read (conf.port + 8, 2, 1, adlib_read, s);
- register_ioport_write (conf.port + 8, 2, 1, adlib_write, s);
-
- qemu_mod_timer (s->ts, qemu_get_clock (vm_clock) + 1);
-}
+++ /dev/null
-/*
- * QEMU Cirrus CLGD 54xx VGA Emulator.
- *
- * Copyright (c) 2004 Fabrice Bellard
- * Copyright (c) 2004 Makoto Suzuki (suzu)
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-/*
- * Reference: Finn Thogersons' VGADOC4b
- * available at http://home.worldonline.dk/~finth/
- */
-#include "vl.h"
-#include "vga_int.h"
-#ifndef _WIN32
-#include <sys/mman.h>
-#endif
-
-/*
- * TODO:
- * - add support for WRITEMASK (GR2F)
- * - optimize linear mappings
- * - optimize bitblt functions
- */
-
-//#define DEBUG_CIRRUS
-//#define DEBUG_BITBLT
-
-/***************************************
- *
- * definitions
- *
- ***************************************/
-
-#define qemu_MIN(a,b) ((a) < (b) ? (a) : (b))
-
-// ID
-#define CIRRUS_ID_CLGD5422 (0x23<<2)
-#define CIRRUS_ID_CLGD5426 (0x24<<2)
-#define CIRRUS_ID_CLGD5424 (0x25<<2)
-#define CIRRUS_ID_CLGD5428 (0x26<<2)
-#define CIRRUS_ID_CLGD5430 (0x28<<2)
-#define CIRRUS_ID_CLGD5434 (0x2A<<2)
-#define CIRRUS_ID_CLGD5436 (0x2B<<2)
-#define CIRRUS_ID_CLGD5446 (0x2E<<2)
-
-// sequencer 0x07
-#define CIRRUS_SR7_BPP_VGA 0x00
-#define CIRRUS_SR7_BPP_SVGA 0x01
-#define CIRRUS_SR7_BPP_MASK 0x0e
-#define CIRRUS_SR7_BPP_8 0x00
-#define CIRRUS_SR7_BPP_16_DOUBLEVCLK 0x02
-#define CIRRUS_SR7_BPP_24 0x04
-#define CIRRUS_SR7_BPP_16 0x06
-#define CIRRUS_SR7_BPP_32 0x08
-#define CIRRUS_SR7_ISAADDR_MASK 0xe0
-
-// sequencer 0x0f
-#define CIRRUS_MEMSIZE_512k 0x08
-#define CIRRUS_MEMSIZE_1M 0x10
-#define CIRRUS_MEMSIZE_2M 0x18
-#define CIRRUS_MEMFLAGS_BANKSWITCH 0x80 // bank switching is enabled.
-
-// sequencer 0x12
-#define CIRRUS_CURSOR_SHOW 0x01
-#define CIRRUS_CURSOR_HIDDENPEL 0x02
-#define CIRRUS_CURSOR_LARGE 0x04 // 64x64 if set, 32x32 if clear
-
-// sequencer 0x17
-#define CIRRUS_BUSTYPE_VLBFAST 0x10
-#define CIRRUS_BUSTYPE_PCI 0x20
-#define CIRRUS_BUSTYPE_VLBSLOW 0x30
-#define CIRRUS_BUSTYPE_ISA 0x38
-#define CIRRUS_MMIO_ENABLE 0x04
-#define CIRRUS_MMIO_USE_PCIADDR 0x40 // 0xb8000 if cleared.
-#define CIRRUS_MEMSIZEEXT_DOUBLE 0x80
-
-// control 0x0b
-#define CIRRUS_BANKING_DUAL 0x01
-#define CIRRUS_BANKING_GRANULARITY_16K 0x20 // set:16k, clear:4k
-
-// control 0x30
-#define CIRRUS_BLTMODE_BACKWARDS 0x01
-#define CIRRUS_BLTMODE_MEMSYSDEST 0x02
-#define CIRRUS_BLTMODE_MEMSYSSRC 0x04
-#define CIRRUS_BLTMODE_TRANSPARENTCOMP 0x08
-#define CIRRUS_BLTMODE_PATTERNCOPY 0x40
-#define CIRRUS_BLTMODE_COLOREXPAND 0x80
-#define CIRRUS_BLTMODE_PIXELWIDTHMASK 0x30
-#define CIRRUS_BLTMODE_PIXELWIDTH8 0x00
-#define CIRRUS_BLTMODE_PIXELWIDTH16 0x10
-#define CIRRUS_BLTMODE_PIXELWIDTH24 0x20
-#define CIRRUS_BLTMODE_PIXELWIDTH32 0x30
-
-// control 0x31
-#define CIRRUS_BLT_BUSY 0x01
-#define CIRRUS_BLT_START 0x02
-#define CIRRUS_BLT_RESET 0x04
-#define CIRRUS_BLT_FIFOUSED 0x10
-#define CIRRUS_BLT_AUTOSTART 0x80
-
-// control 0x32
-#define CIRRUS_ROP_0 0x00
-#define CIRRUS_ROP_SRC_AND_DST 0x05
-#define CIRRUS_ROP_NOP 0x06
-#define CIRRUS_ROP_SRC_AND_NOTDST 0x09
-#define CIRRUS_ROP_NOTDST 0x0b
-#define CIRRUS_ROP_SRC 0x0d
-#define CIRRUS_ROP_1 0x0e
-#define CIRRUS_ROP_NOTSRC_AND_DST 0x50
-#define CIRRUS_ROP_SRC_XOR_DST 0x59
-#define CIRRUS_ROP_SRC_OR_DST 0x6d
-#define CIRRUS_ROP_NOTSRC_OR_NOTDST 0x90
-#define CIRRUS_ROP_SRC_NOTXOR_DST 0x95
-#define CIRRUS_ROP_SRC_OR_NOTDST 0xad
-#define CIRRUS_ROP_NOTSRC 0xd0
-#define CIRRUS_ROP_NOTSRC_OR_DST 0xd6
-#define CIRRUS_ROP_NOTSRC_AND_NOTDST 0xda
-
-#define CIRRUS_ROP_NOP_INDEX 2
-#define CIRRUS_ROP_SRC_INDEX 5
-
-// control 0x33
-#define CIRRUS_BLTMODEEXT_SOLIDFILL 0x04
-#define CIRRUS_BLTMODEEXT_COLOREXPINV 0x02
-#define CIRRUS_BLTMODEEXT_DWORDGRANULARITY 0x01
-
-// memory-mapped IO
-#define CIRRUS_MMIO_BLTBGCOLOR 0x00 // dword
-#define CIRRUS_MMIO_BLTFGCOLOR 0x04 // dword
-#define CIRRUS_MMIO_BLTWIDTH 0x08 // word
-#define CIRRUS_MMIO_BLTHEIGHT 0x0a // word
-#define CIRRUS_MMIO_BLTDESTPITCH 0x0c // word
-#define CIRRUS_MMIO_BLTSRCPITCH 0x0e // word
-#define CIRRUS_MMIO_BLTDESTADDR 0x10 // dword
-#define CIRRUS_MMIO_BLTSRCADDR 0x14 // dword
-#define CIRRUS_MMIO_BLTWRITEMASK 0x17 // byte
-#define CIRRUS_MMIO_BLTMODE 0x18 // byte
-#define CIRRUS_MMIO_BLTROP 0x1a // byte
-#define CIRRUS_MMIO_BLTMODEEXT 0x1b // byte
-#define CIRRUS_MMIO_BLTTRANSPARENTCOLOR 0x1c // word?
-#define CIRRUS_MMIO_BLTTRANSPARENTCOLORMASK 0x20 // word?
-#define CIRRUS_MMIO_LINEARDRAW_START_X 0x24 // word
-#define CIRRUS_MMIO_LINEARDRAW_START_Y 0x26 // word
-#define CIRRUS_MMIO_LINEARDRAW_END_X 0x28 // word
-#define CIRRUS_MMIO_LINEARDRAW_END_Y 0x2a // word
-#define CIRRUS_MMIO_LINEARDRAW_LINESTYLE_INC 0x2c // byte
-#define CIRRUS_MMIO_LINEARDRAW_LINESTYLE_ROLLOVER 0x2d // byte
-#define CIRRUS_MMIO_LINEARDRAW_LINESTYLE_MASK 0x2e // byte
-#define CIRRUS_MMIO_LINEARDRAW_LINESTYLE_ACCUM 0x2f // byte
-#define CIRRUS_MMIO_BRESENHAM_K1 0x30 // word
-#define CIRRUS_MMIO_BRESENHAM_K3 0x32 // word
-#define CIRRUS_MMIO_BRESENHAM_ERROR 0x34 // word
-#define CIRRUS_MMIO_BRESENHAM_DELTA_MAJOR 0x36 // word
-#define CIRRUS_MMIO_BRESENHAM_DIRECTION 0x38 // byte
-#define CIRRUS_MMIO_LINEDRAW_MODE 0x39 // byte
-#define CIRRUS_MMIO_BLTSTATUS 0x40 // byte
-
-// PCI 0x00: vendor, 0x02: device
-#define PCI_VENDOR_CIRRUS 0x1013
-#define PCI_DEVICE_CLGD5462 0x00d0
-#define PCI_DEVICE_CLGD5465 0x00d6
-
-// PCI 0x04: command(word), 0x06(word): status
-#define PCI_COMMAND_IOACCESS 0x0001
-#define PCI_COMMAND_MEMACCESS 0x0002
-#define PCI_COMMAND_BUSMASTER 0x0004
-#define PCI_COMMAND_SPECIALCYCLE 0x0008
-#define PCI_COMMAND_MEMWRITEINVALID 0x0010
-#define PCI_COMMAND_PALETTESNOOPING 0x0020
-#define PCI_COMMAND_PARITYDETECTION 0x0040
-#define PCI_COMMAND_ADDRESSDATASTEPPING 0x0080
-#define PCI_COMMAND_SERR 0x0100
-#define PCI_COMMAND_BACKTOBACKTRANS 0x0200
-// PCI 0x08, 0xff000000 (0x09-0x0b:class,0x08:rev)
-#define PCI_CLASS_BASE_DISPLAY 0x03
-// PCI 0x08, 0x00ff0000
-#define PCI_CLASS_SUB_VGA 0x00
-// PCI 0x0c, 0x00ff0000 (0x0c:cacheline,0x0d:latency,0x0e:headertype,0x0f:Built-in self test)
-#define PCI_CLASS_HEADERTYPE_00h 0x00
-// 0x10-0x3f (headertype 00h)
-// PCI 0x10,0x14,0x18,0x1c,0x20,0x24: base address mapping registers
-// 0x10: MEMBASE, 0x14: IOBASE(hard-coded in XFree86 3.x)
-#define PCI_MAP_MEM 0x0
-#define PCI_MAP_IO 0x1
-#define PCI_MAP_MEM_ADDR_MASK (~0xf)
-#define PCI_MAP_IO_ADDR_MASK (~0x3)
-#define PCI_MAP_MEMFLAGS_32BIT 0x0
-#define PCI_MAP_MEMFLAGS_32BIT_1M 0x1
-#define PCI_MAP_MEMFLAGS_64BIT 0x4
-#define PCI_MAP_MEMFLAGS_CACHEABLE 0x8
-// PCI 0x28: cardbus CIS pointer
-// PCI 0x2c: subsystem vendor id, 0x2e: subsystem id
-// PCI 0x30: expansion ROM base address
-#define PCI_ROMBIOS_ENABLED 0x1
-// PCI 0x34: 0xffffff00=reserved, 0x000000ff=capabilities pointer
-// PCI 0x38: reserved
-// PCI 0x3c: 0x3c=int-line, 0x3d=int-pin, 0x3e=min-gnt, 0x3f=maax-lat
-
-#define CIRRUS_PNPMMIO_SIZE 0x1000
-
-
-/* I/O and memory hook */
-#define CIRRUS_HOOK_NOT_HANDLED 0
-#define CIRRUS_HOOK_HANDLED 1
-
-struct CirrusVGAState;
-typedef void (*cirrus_bitblt_rop_t) (struct CirrusVGAState *s,
- uint8_t * dst, const uint8_t * src,
- int dstpitch, int srcpitch,
- int bltwidth, int bltheight);
-typedef void (*cirrus_fill_t)(struct CirrusVGAState *s,
- uint8_t *dst, int dst_pitch, int width, int height);
-
-typedef struct CirrusVGAState {
- VGA_STATE_COMMON
-
- int cirrus_linear_io_addr;
- int cirrus_linear_bitblt_io_addr;
- int cirrus_mmio_io_addr;
- unsigned long cirrus_lfb_addr;
- unsigned long cirrus_lfb_end;
- uint32_t cirrus_addr_mask;
- uint32_t linear_mmio_mask;
- uint8_t cirrus_shadow_gr0;
- uint8_t cirrus_shadow_gr1;
- uint8_t cirrus_hidden_dac_lockindex;
- uint8_t cirrus_hidden_dac_data;
- uint32_t cirrus_bank_base[2];
- uint32_t cirrus_bank_limit[2];
- uint8_t cirrus_hidden_palette[48];
- uint32_t hw_cursor_x;
- uint32_t hw_cursor_y;
- int cirrus_blt_pixelwidth;
- int cirrus_blt_width;
- int cirrus_blt_height;
- int cirrus_blt_dstpitch;
- int cirrus_blt_srcpitch;
- uint32_t cirrus_blt_fgcol;
- uint32_t cirrus_blt_bgcol;
- uint32_t cirrus_blt_dstaddr;
- uint32_t cirrus_blt_srcaddr;
- uint8_t cirrus_blt_mode;
- uint8_t cirrus_blt_modeext;
- cirrus_bitblt_rop_t cirrus_rop;
-#define CIRRUS_BLTBUFSIZE (2048 * 4) /* one line width */
- uint8_t cirrus_bltbuf[CIRRUS_BLTBUFSIZE];
- uint8_t *cirrus_srcptr;
- uint8_t *cirrus_srcptr_end;
- uint32_t cirrus_srccounter;
- /* hwcursor display state */
- int last_hw_cursor_size;
- int last_hw_cursor_x;
- int last_hw_cursor_y;
- int last_hw_cursor_y_start;
- int last_hw_cursor_y_end;
- int real_vram_size; /* XXX: suppress that */
- CPUWriteMemoryFunc **cirrus_linear_write;
- unsigned long map_addr;
- unsigned long map_end;
-} CirrusVGAState;
-
-typedef struct PCICirrusVGAState {
- PCIDevice dev;
- CirrusVGAState cirrus_vga;
-} PCICirrusVGAState;
-
-static uint8_t rop_to_index[256];
-
-/***************************************
- *
- * prototypes.
- *
- ***************************************/
-
-
-static void cirrus_bitblt_reset(CirrusVGAState *s);
-static void cirrus_update_memory_access(CirrusVGAState *s);
-
-/***************************************
- *
- * raster operations
- *
- ***************************************/
-
-static void cirrus_bitblt_rop_nop(CirrusVGAState *s,
- uint8_t *dst,const uint8_t *src,
- int dstpitch,int srcpitch,
- int bltwidth,int bltheight)
-{
-}
-
-static void cirrus_bitblt_fill_nop(CirrusVGAState *s,
- uint8_t *dst,
- int dstpitch, int bltwidth,int bltheight)
-{
-}
-
-#define ROP_NAME 0
-#define ROP_OP(d, s) d = 0
-#include "cirrus_vga_rop.h"
-
-#define ROP_NAME src_and_dst
-#define ROP_OP(d, s) d = (s) & (d)
-#include "cirrus_vga_rop.h"
-
-#define ROP_NAME src_and_notdst
-#define ROP_OP(d, s) d = (s) & (~(d))
-#include "cirrus_vga_rop.h"
-
-#define ROP_NAME notdst
-#define ROP_OP(d, s) d = ~(d)
-#include "cirrus_vga_rop.h"
-
-#define ROP_NAME src
-#define ROP_OP(d, s) d = s
-#include "cirrus_vga_rop.h"
-
-#define ROP_NAME 1
-#define ROP_OP(d, s) d = ~0
-#include "cirrus_vga_rop.h"
-
-#define ROP_NAME notsrc_and_dst
-#define ROP_OP(d, s) d = (~(s)) & (d)
-#include "cirrus_vga_rop.h"
-
-#define ROP_NAME src_xor_dst
-#define ROP_OP(d, s) d = (s) ^ (d)
-#include "cirrus_vga_rop.h"
-
-#define ROP_NAME src_or_dst
-#define ROP_OP(d, s) d = (s) | (d)
-#include "cirrus_vga_rop.h"
-
-#define ROP_NAME notsrc_or_notdst
-#define ROP_OP(d, s) d = (~(s)) | (~(d))
-#include "cirrus_vga_rop.h"
-
-#define ROP_NAME src_notxor_dst
-#define ROP_OP(d, s) d = ~((s) ^ (d))
-#include "cirrus_vga_rop.h"
-
-#define ROP_NAME src_or_notdst
-#define ROP_OP(d, s) d = (s) | (~(d))
-#include "cirrus_vga_rop.h"
-
-#define ROP_NAME notsrc
-#define ROP_OP(d, s) d = (~(s))
-#include "cirrus_vga_rop.h"
-
-#define ROP_NAME notsrc_or_dst
-#define ROP_OP(d, s) d = (~(s)) | (d)
-#include "cirrus_vga_rop.h"
-
-#define ROP_NAME notsrc_and_notdst
-#define ROP_OP(d, s) d = (~(s)) & (~(d))
-#include "cirrus_vga_rop.h"
-
-static const cirrus_bitblt_rop_t cirrus_fwd_rop[16] = {
- cirrus_bitblt_rop_fwd_0,
- cirrus_bitblt_rop_fwd_src_and_dst,
- cirrus_bitblt_rop_nop,
- cirrus_bitblt_rop_fwd_src_and_notdst,
- cirrus_bitblt_rop_fwd_notdst,
- cirrus_bitblt_rop_fwd_src,
- cirrus_bitblt_rop_fwd_1,
- cirrus_bitblt_rop_fwd_notsrc_and_dst,
- cirrus_bitblt_rop_fwd_src_xor_dst,
- cirrus_bitblt_rop_fwd_src_or_dst,
- cirrus_bitblt_rop_fwd_notsrc_or_notdst,
- cirrus_bitblt_rop_fwd_src_notxor_dst,
- cirrus_bitblt_rop_fwd_src_or_notdst,
- cirrus_bitblt_rop_fwd_notsrc,
- cirrus_bitblt_rop_fwd_notsrc_or_dst,
- cirrus_bitblt_rop_fwd_notsrc_and_notdst,
-};
-
-static const cirrus_bitblt_rop_t cirrus_bkwd_rop[16] = {
- cirrus_bitblt_rop_bkwd_0,
- cirrus_bitblt_rop_bkwd_src_and_dst,
- cirrus_bitblt_rop_nop,
- cirrus_bitblt_rop_bkwd_src_and_notdst,
- cirrus_bitblt_rop_bkwd_notdst,
- cirrus_bitblt_rop_bkwd_src,
- cirrus_bitblt_rop_bkwd_1,
- cirrus_bitblt_rop_bkwd_notsrc_and_dst,
- cirrus_bitblt_rop_bkwd_src_xor_dst,
- cirrus_bitblt_rop_bkwd_src_or_dst,
- cirrus_bitblt_rop_bkwd_notsrc_or_notdst,
- cirrus_bitblt_rop_bkwd_src_notxor_dst,
- cirrus_bitblt_rop_bkwd_src_or_notdst,
- cirrus_bitblt_rop_bkwd_notsrc,
- cirrus_bitblt_rop_bkwd_notsrc_or_dst,
- cirrus_bitblt_rop_bkwd_notsrc_and_notdst,
-};
-
-#define ROP2(name) {\
- name ## _8,\
- name ## _16,\
- name ## _24,\
- name ## _32,\
- }
-
-#define ROP_NOP2(func) {\
- func,\
- func,\
- func,\
- func,\
- }
-
-static const cirrus_bitblt_rop_t cirrus_patternfill[16][4] = {
- ROP2(cirrus_patternfill_0),
- ROP2(cirrus_patternfill_src_and_dst),
- ROP_NOP2(cirrus_bitblt_rop_nop),
- ROP2(cirrus_patternfill_src_and_notdst),
- ROP2(cirrus_patternfill_notdst),
- ROP2(cirrus_patternfill_src),
- ROP2(cirrus_patternfill_1),
- ROP2(cirrus_patternfill_notsrc_and_dst),
- ROP2(cirrus_patternfill_src_xor_dst),
- ROP2(cirrus_patternfill_src_or_dst),
- ROP2(cirrus_patternfill_notsrc_or_notdst),
- ROP2(cirrus_patternfill_src_notxor_dst),
- ROP2(cirrus_patternfill_src_or_notdst),
- ROP2(cirrus_patternfill_notsrc),
- ROP2(cirrus_patternfill_notsrc_or_dst),
- ROP2(cirrus_patternfill_notsrc_and_notdst),
-};
-
-static const cirrus_bitblt_rop_t cirrus_colorexpand_transp[16][4] = {
- ROP2(cirrus_colorexpand_transp_0),
- ROP2(cirrus_colorexpand_transp_src_and_dst),
- ROP_NOP2(cirrus_bitblt_rop_nop),
- ROP2(cirrus_colorexpand_transp_src_and_notdst),
- ROP2(cirrus_colorexpand_transp_notdst),
- ROP2(cirrus_colorexpand_transp_src),
- ROP2(cirrus_colorexpand_transp_1),
- ROP2(cirrus_colorexpand_transp_notsrc_and_dst),
- ROP2(cirrus_colorexpand_transp_src_xor_dst),
- ROP2(cirrus_colorexpand_transp_src_or_dst),
- ROP2(cirrus_colorexpand_transp_notsrc_or_notdst),
- ROP2(cirrus_colorexpand_transp_src_notxor_dst),
- ROP2(cirrus_colorexpand_transp_src_or_notdst),
- ROP2(cirrus_colorexpand_transp_notsrc),
- ROP2(cirrus_colorexpand_transp_notsrc_or_dst),
- ROP2(cirrus_colorexpand_transp_notsrc_and_notdst),
-};
-
-static const cirrus_bitblt_rop_t cirrus_colorexpand[16][4] = {
- ROP2(cirrus_colorexpand_0),
- ROP2(cirrus_colorexpand_src_and_dst),
- ROP_NOP2(cirrus_bitblt_rop_nop),
- ROP2(cirrus_colorexpand_src_and_notdst),
- ROP2(cirrus_colorexpand_notdst),
- ROP2(cirrus_colorexpand_src),
- ROP2(cirrus_colorexpand_1),
- ROP2(cirrus_colorexpand_notsrc_and_dst),
- ROP2(cirrus_colorexpand_src_xor_dst),
- ROP2(cirrus_colorexpand_src_or_dst),
- ROP2(cirrus_colorexpand_notsrc_or_notdst),
- ROP2(cirrus_colorexpand_src_notxor_dst),
- ROP2(cirrus_colorexpand_src_or_notdst),
- ROP2(cirrus_colorexpand_notsrc),
- ROP2(cirrus_colorexpand_notsrc_or_dst),
- ROP2(cirrus_colorexpand_notsrc_and_notdst),
-};
-
-static const cirrus_bitblt_rop_t cirrus_colorexpand_pattern_transp[16][4] = {
- ROP2(cirrus_colorexpand_pattern_transp_0),
- ROP2(cirrus_colorexpand_pattern_transp_src_and_dst),
- ROP_NOP2(cirrus_bitblt_rop_nop),
- ROP2(cirrus_colorexpand_pattern_transp_src_and_notdst),
- ROP2(cirrus_colorexpand_pattern_transp_notdst),
- ROP2(cirrus_colorexpand_pattern_transp_src),
- ROP2(cirrus_colorexpand_pattern_transp_1),
- ROP2(cirrus_colorexpand_pattern_transp_notsrc_and_dst),
- ROP2(cirrus_colorexpand_pattern_transp_src_xor_dst),
- ROP2(cirrus_colorexpand_pattern_transp_src_or_dst),
- ROP2(cirrus_colorexpand_pattern_transp_notsrc_or_notdst),
- ROP2(cirrus_colorexpand_pattern_transp_src_notxor_dst),
- ROP2(cirrus_colorexpand_pattern_transp_src_or_notdst),
- ROP2(cirrus_colorexpand_pattern_transp_notsrc),
- ROP2(cirrus_colorexpand_pattern_transp_notsrc_or_dst),
- ROP2(cirrus_colorexpand_pattern_transp_notsrc_and_notdst),
-};
-
-static const cirrus_bitblt_rop_t cirrus_colorexpand_pattern[16][4] = {
- ROP2(cirrus_colorexpand_pattern_0),
- ROP2(cirrus_colorexpand_pattern_src_and_dst),
- ROP_NOP2(cirrus_bitblt_rop_nop),
- ROP2(cirrus_colorexpand_pattern_src_and_notdst),
- ROP2(cirrus_colorexpand_pattern_notdst),
- ROP2(cirrus_colorexpand_pattern_src),
- ROP2(cirrus_colorexpand_pattern_1),
- ROP2(cirrus_colorexpand_pattern_notsrc_and_dst),
- ROP2(cirrus_colorexpand_pattern_src_xor_dst),
- ROP2(cirrus_colorexpand_pattern_src_or_dst),
- ROP2(cirrus_colorexpand_pattern_notsrc_or_notdst),
- ROP2(cirrus_colorexpand_pattern_src_notxor_dst),
- ROP2(cirrus_colorexpand_pattern_src_or_notdst),
- ROP2(cirrus_colorexpand_pattern_notsrc),
- ROP2(cirrus_colorexpand_pattern_notsrc_or_dst),
- ROP2(cirrus_colorexpand_pattern_notsrc_and_notdst),
-};
-
-static const cirrus_fill_t cirrus_fill[16][4] = {
- ROP2(cirrus_fill_0),
- ROP2(cirrus_fill_src_and_dst),
- ROP_NOP2(cirrus_bitblt_fill_nop),
- ROP2(cirrus_fill_src_and_notdst),
- ROP2(cirrus_fill_notdst),
- ROP2(cirrus_fill_src),
- ROP2(cirrus_fill_1),
- ROP2(cirrus_fill_notsrc_and_dst),
- ROP2(cirrus_fill_src_xor_dst),
- ROP2(cirrus_fill_src_or_dst),
- ROP2(cirrus_fill_notsrc_or_notdst),
- ROP2(cirrus_fill_src_notxor_dst),
- ROP2(cirrus_fill_src_or_notdst),
- ROP2(cirrus_fill_notsrc),
- ROP2(cirrus_fill_notsrc_or_dst),
- ROP2(cirrus_fill_notsrc_and_notdst),
-};
-
-static inline void cirrus_bitblt_fgcol(CirrusVGAState *s)
-{
- unsigned int color;
- switch (s->cirrus_blt_pixelwidth) {
- case 1:
- s->cirrus_blt_fgcol = s->cirrus_shadow_gr1;
- break;
- case 2:
- color = s->cirrus_shadow_gr1 | (s->gr[0x11] << 8);
- s->cirrus_blt_fgcol = le16_to_cpu(color);
- break;
- case 3:
- s->cirrus_blt_fgcol = s->cirrus_shadow_gr1 |
- (s->gr[0x11] << 8) | (s->gr[0x13] << 16);
- break;
- default:
- case 4:
- color = s->cirrus_shadow_gr1 | (s->gr[0x11] << 8) |
- (s->gr[0x13] << 16) | (s->gr[0x15] << 24);
- s->cirrus_blt_fgcol = le32_to_cpu(color);
- break;
- }
-}
-
-static inline void cirrus_bitblt_bgcol(CirrusVGAState *s)
-{
- unsigned int color;
- switch (s->cirrus_blt_pixelwidth) {
- case 1:
- s->cirrus_blt_bgcol = s->cirrus_shadow_gr0;
- break;
- case 2:
- color = s->cirrus_shadow_gr0 | (s->gr[0x10] << 8);
- s->cirrus_blt_bgcol = le16_to_cpu(color);
- break;
- case 3:
- s->cirrus_blt_bgcol = s->cirrus_shadow_gr0 |
- (s->gr[0x10] << 8) | (s->gr[0x12] << 16);
- break;
- default:
- case 4:
- color = s->cirrus_shadow_gr0 | (s->gr[0x10] << 8) |
- (s->gr[0x12] << 16) | (s->gr[0x14] << 24);
- s->cirrus_blt_bgcol = le32_to_cpu(color);
- break;
- }
-}
-
-static void cirrus_invalidate_region(CirrusVGAState * s, int off_begin,
- int off_pitch, int bytesperline,
- int lines)
-{
- int y;
- int off_cur;
- int off_cur_end;
-
- for (y = 0; y < lines; y++) {
- off_cur = off_begin;
- off_cur_end = off_cur + bytesperline;
- off_cur &= TARGET_PAGE_MASK;
- while (off_cur < off_cur_end) {
- cpu_physical_memory_set_dirty(s->vram_offset + off_cur);
- off_cur += TARGET_PAGE_SIZE;
- }
- off_begin += off_pitch;
- }
-}
-
-static int cirrus_bitblt_common_patterncopy(CirrusVGAState * s,
- const uint8_t * src)
-{
- uint8_t *dst;
-
- dst = s->vram_ptr + s->cirrus_blt_dstaddr;
- (*s->cirrus_rop) (s, dst, src,
- s->cirrus_blt_dstpitch, 0,
- s->cirrus_blt_width, s->cirrus_blt_height);
- cirrus_invalidate_region(s, s->cirrus_blt_dstaddr,
- s->cirrus_blt_dstpitch, s->cirrus_blt_width,
- s->cirrus_blt_height);
- return 1;
-}
-
-/* fill */
-
-static int cirrus_bitblt_solidfill(CirrusVGAState *s, int blt_rop)
-{
- cirrus_fill_t rop_func;
-
- rop_func = cirrus_fill[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];
- rop_func(s, s->vram_ptr + s->cirrus_blt_dstaddr,
- s->cirrus_blt_dstpitch,
- s->cirrus_blt_width, s->cirrus_blt_height);
- cirrus_invalidate_region(s, s->cirrus_blt_dstaddr,
- s->cirrus_blt_dstpitch, s->cirrus_blt_width,
- s->cirrus_blt_height);
- cirrus_bitblt_reset(s);
- return 1;
-}
-
-/***************************************
- *
- * bitblt (video-to-video)
- *
- ***************************************/
-
-static int cirrus_bitblt_videotovideo_patterncopy(CirrusVGAState * s)
-{
- return cirrus_bitblt_common_patterncopy(s,
- s->vram_ptr +
- (s->cirrus_blt_srcaddr & ~7));
-}
-
-static int cirrus_bitblt_videotovideo_copy(CirrusVGAState * s)
-{
- (*s->cirrus_rop) (s, s->vram_ptr + s->cirrus_blt_dstaddr,
- s->vram_ptr + s->cirrus_blt_srcaddr,
- s->cirrus_blt_dstpitch, s->cirrus_blt_srcpitch,
- s->cirrus_blt_width, s->cirrus_blt_height);
- cirrus_invalidate_region(s, s->cirrus_blt_dstaddr,
- s->cirrus_blt_dstpitch, s->cirrus_blt_width,
- s->cirrus_blt_height);
- return 1;
-}
-
-/***************************************
- *
- * bitblt (cpu-to-video)
- *
- ***************************************/
-
-static void cirrus_bitblt_cputovideo_next(CirrusVGAState * s)
-{
- int copy_count;
- uint8_t *end_ptr;
-
- if (s->cirrus_srccounter > 0) {
- if (s->cirrus_blt_mode & CIRRUS_BLTMODE_PATTERNCOPY) {
- cirrus_bitblt_common_patterncopy(s, s->cirrus_bltbuf);
- the_end:
- s->cirrus_srccounter = 0;
- cirrus_bitblt_reset(s);
- } else {
- /* at least one scan line */
- do {
- (*s->cirrus_rop)(s, s->vram_ptr + s->cirrus_blt_dstaddr,
- s->cirrus_bltbuf, 0, 0, s->cirrus_blt_width, 1);
- cirrus_invalidate_region(s, s->cirrus_blt_dstaddr, 0,
- s->cirrus_blt_width, 1);
- s->cirrus_blt_dstaddr += s->cirrus_blt_dstpitch;
- s->cirrus_srccounter -= s->cirrus_blt_srcpitch;
- if (s->cirrus_srccounter <= 0)
- goto the_end;
- /* more bytes than needed can be transfered because of
- word alignment, so we keep them for the next line */
- /* XXX: keep alignment to speed up transfer */
- end_ptr = s->cirrus_bltbuf + s->cirrus_blt_srcpitch;
- copy_count = s->cirrus_srcptr_end - end_ptr;
- memmove(s->cirrus_bltbuf, end_ptr, copy_count);
- s->cirrus_srcptr = s->cirrus_bltbuf + copy_count;
- s->cirrus_srcptr_end = s->cirrus_bltbuf + s->cirrus_blt_srcpitch;
- } while (s->cirrus_srcptr >= s->cirrus_srcptr_end);
- }
- }
-}
-
-/***************************************
- *
- * bitblt wrapper
- *
- ***************************************/
-
-static void cirrus_bitblt_reset(CirrusVGAState * s)
-{
- s->gr[0x31] &=
- ~(CIRRUS_BLT_START | CIRRUS_BLT_BUSY | CIRRUS_BLT_FIFOUSED);
- s->cirrus_srcptr = &s->cirrus_bltbuf[0];
- s->cirrus_srcptr_end = &s->cirrus_bltbuf[0];
- s->cirrus_srccounter = 0;
- cirrus_update_memory_access(s);
-}
-
-static int cirrus_bitblt_cputovideo(CirrusVGAState * s)
-{
- int w;
-
- s->cirrus_blt_mode &= ~CIRRUS_BLTMODE_MEMSYSSRC;
- s->cirrus_srcptr = &s->cirrus_bltbuf[0];
- s->cirrus_srcptr_end = &s->cirrus_bltbuf[0];
-
- if (s->cirrus_blt_mode & CIRRUS_BLTMODE_PATTERNCOPY) {
- if (s->cirrus_blt_mode & CIRRUS_BLTMODE_COLOREXPAND) {
- s->cirrus_blt_srcpitch = 8;
- } else {
- /* XXX: check for 24 bpp */
- s->cirrus_blt_srcpitch = 8 * 8 * s->cirrus_blt_pixelwidth;
- }
- s->cirrus_srccounter = s->cirrus_blt_srcpitch;
- } else {
- if (s->cirrus_blt_mode & CIRRUS_BLTMODE_COLOREXPAND) {
- w = s->cirrus_blt_width / s->cirrus_blt_pixelwidth;
- if (s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_DWORDGRANULARITY)
- s->cirrus_blt_srcpitch = ((w + 31) >> 5);
- else
- s->cirrus_blt_srcpitch = ((w + 7) >> 3);
- } else {
- s->cirrus_blt_srcpitch = s->cirrus_blt_width;
- }
- s->cirrus_srccounter = s->cirrus_blt_srcpitch * s->cirrus_blt_height;
- }
- s->cirrus_srcptr = s->cirrus_bltbuf;
- s->cirrus_srcptr_end = s->cirrus_bltbuf + s->cirrus_blt_srcpitch;
- cirrus_update_memory_access(s);
- return 1;
-}
-
-static int cirrus_bitblt_videotocpu(CirrusVGAState * s)
-{
- /* XXX */
-#ifdef DEBUG_BITBLT
- printf("cirrus: bitblt (video to cpu) is not implemented yet\n");
-#endif
- return 0;
-}
-
-static int cirrus_bitblt_videotovideo(CirrusVGAState * s)
-{
- int ret;
-
- if (s->cirrus_blt_mode & CIRRUS_BLTMODE_PATTERNCOPY) {
- ret = cirrus_bitblt_videotovideo_patterncopy(s);
- } else {
- ret = cirrus_bitblt_videotovideo_copy(s);
- }
- if (ret)
- cirrus_bitblt_reset(s);
- return ret;
-}
-
-static void cirrus_bitblt_start(CirrusVGAState * s)
-{
- uint8_t blt_rop;
-
- s->gr[0x31] |= CIRRUS_BLT_BUSY;
-
- s->cirrus_blt_width = (s->gr[0x20] | (s->gr[0x21] << 8)) + 1;
- s->cirrus_blt_height = (s->gr[0x22] | (s->gr[0x23] << 8)) + 1;
- s->cirrus_blt_dstpitch = (s->gr[0x24] | (s->gr[0x25] << 8));
- s->cirrus_blt_srcpitch = (s->gr[0x26] | (s->gr[0x27] << 8));
- s->cirrus_blt_dstaddr =
- (s->gr[0x28] | (s->gr[0x29] << 8) | (s->gr[0x2a] << 16));
- s->cirrus_blt_srcaddr =
- (s->gr[0x2c] | (s->gr[0x2d] << 8) | (s->gr[0x2e] << 16));
- s->cirrus_blt_mode = s->gr[0x30];
- s->cirrus_blt_modeext = s->gr[0x33];
- blt_rop = s->gr[0x32];
-
-#ifdef DEBUG_BITBLT
- printf("rop=0x%02x mode=0x%02x modeext=0x%02x w=%d h=%d dpitch=%d spicth=%d daddr=0x%08x saddr=0x%08x writemask=0x%02x\n",
- blt_rop,
- s->cirrus_blt_mode,
- s->cirrus_blt_modeext,
- s->cirrus_blt_width,
- s->cirrus_blt_height,
- s->cirrus_blt_dstpitch,
- s->cirrus_blt_srcpitch,
- s->cirrus_blt_dstaddr,
- s->cirrus_blt_srcaddr,
- s->sr[0x2f]);
-#endif
-
- switch (s->cirrus_blt_mode & CIRRUS_BLTMODE_PIXELWIDTHMASK) {
- case CIRRUS_BLTMODE_PIXELWIDTH8:
- s->cirrus_blt_pixelwidth = 1;
- break;
- case CIRRUS_BLTMODE_PIXELWIDTH16:
- s->cirrus_blt_pixelwidth = 2;
- break;
- case CIRRUS_BLTMODE_PIXELWIDTH24:
- s->cirrus_blt_pixelwidth = 3;
- break;
- case CIRRUS_BLTMODE_PIXELWIDTH32:
- s->cirrus_blt_pixelwidth = 4;
- break;
- default:
-#ifdef DEBUG_BITBLT
- printf("cirrus: bitblt - pixel width is unknown\n");
-#endif
- goto bitblt_ignore;
- }
- s->cirrus_blt_mode &= ~CIRRUS_BLTMODE_PIXELWIDTHMASK;
-
- if ((s->
- cirrus_blt_mode & (CIRRUS_BLTMODE_MEMSYSSRC |
- CIRRUS_BLTMODE_MEMSYSDEST))
- == (CIRRUS_BLTMODE_MEMSYSSRC | CIRRUS_BLTMODE_MEMSYSDEST)) {
-#ifdef DEBUG_BITBLT
- printf("cirrus: bitblt - memory-to-memory copy is requested\n");
-#endif
- goto bitblt_ignore;
- }
-
- if ((s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_SOLIDFILL) &&
- (s->cirrus_blt_mode & (CIRRUS_BLTMODE_MEMSYSDEST |
- CIRRUS_BLTMODE_TRANSPARENTCOMP |
- CIRRUS_BLTMODE_PATTERNCOPY |
- CIRRUS_BLTMODE_COLOREXPAND)) ==
- (CIRRUS_BLTMODE_PATTERNCOPY | CIRRUS_BLTMODE_COLOREXPAND)) {
- cirrus_bitblt_fgcol(s);
- cirrus_bitblt_solidfill(s, blt_rop);
- } else {
- if ((s->cirrus_blt_mode & (CIRRUS_BLTMODE_COLOREXPAND |
- CIRRUS_BLTMODE_PATTERNCOPY)) ==
- CIRRUS_BLTMODE_COLOREXPAND) {
-
- if (s->cirrus_blt_mode & CIRRUS_BLTMODE_TRANSPARENTCOMP) {
- if (s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_COLOREXPINV)
- cirrus_bitblt_bgcol(s);
- else
- cirrus_bitblt_fgcol(s);
- s->cirrus_rop = cirrus_colorexpand_transp[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];
- } else {
- cirrus_bitblt_fgcol(s);
- cirrus_bitblt_bgcol(s);
- s->cirrus_rop = cirrus_colorexpand[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];
- }
- } else if (s->cirrus_blt_mode & CIRRUS_BLTMODE_PATTERNCOPY) {
- if (s->cirrus_blt_mode & CIRRUS_BLTMODE_COLOREXPAND) {
- if (s->cirrus_blt_mode & CIRRUS_BLTMODE_TRANSPARENTCOMP) {
- if (s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_COLOREXPINV)
- cirrus_bitblt_bgcol(s);
- else
- cirrus_bitblt_fgcol(s);
- s->cirrus_rop = cirrus_colorexpand_pattern_transp[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];
- } else {
- cirrus_bitblt_fgcol(s);
- cirrus_bitblt_bgcol(s);
- s->cirrus_rop = cirrus_colorexpand_pattern[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];
- }
- } else {
- s->cirrus_rop = cirrus_patternfill[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];
- }
- } else {
- if (s->cirrus_blt_mode & CIRRUS_BLTMODE_BACKWARDS) {
- s->cirrus_blt_dstpitch = -s->cirrus_blt_dstpitch;
- s->cirrus_blt_srcpitch = -s->cirrus_blt_srcpitch;
- s->cirrus_rop = cirrus_bkwd_rop[rop_to_index[blt_rop]];
- } else {
- s->cirrus_rop = cirrus_fwd_rop[rop_to_index[blt_rop]];
- }
- }
-
- // setup bitblt engine.
- if (s->cirrus_blt_mode & CIRRUS_BLTMODE_MEMSYSSRC) {
- if (!cirrus_bitblt_cputovideo(s))
- goto bitblt_ignore;
- } else if (s->cirrus_blt_mode & CIRRUS_BLTMODE_MEMSYSDEST) {
- if (!cirrus_bitblt_videotocpu(s))
- goto bitblt_ignore;
- } else {
- if (!cirrus_bitblt_videotovideo(s))
- goto bitblt_ignore;
- }
- }
- return;
- bitblt_ignore:;
- cirrus_bitblt_reset(s);
-}
-
-static void cirrus_write_bitblt(CirrusVGAState * s, unsigned reg_value)
-{
- unsigned old_value;
-
- old_value = s->gr[0x31];
- s->gr[0x31] = reg_value;
-
- if (((old_value & CIRRUS_BLT_RESET) != 0) &&
- ((reg_value & CIRRUS_BLT_RESET) == 0)) {
- cirrus_bitblt_reset(s);
- } else if (((old_value & CIRRUS_BLT_START) == 0) &&
- ((reg_value & CIRRUS_BLT_START) != 0)) {
- cirrus_bitblt_start(s);
- }
-}
-
-
-/***************************************
- *
- * basic parameters
- *
- ***************************************/
-
-static void cirrus_get_offsets(VGAState *s1,
- uint32_t *pline_offset,
- uint32_t *pstart_addr)
-{
- CirrusVGAState * s = (CirrusVGAState *)s1;
- uint32_t start_addr;
- uint32_t line_offset;
-
- line_offset = s->cr[0x13]
- | ((s->cr[0x1b] & 0x10) << 4);
- line_offset <<= 3;
- *pline_offset = line_offset;
-
- start_addr = (s->cr[0x0c] << 8)
- | s->cr[0x0d]
- | ((s->cr[0x1b] & 0x01) << 16)
- | ((s->cr[0x1b] & 0x0c) << 15)
- | ((s->cr[0x1d] & 0x80) << 12);
- *pstart_addr = start_addr;
-}
-
-static uint32_t cirrus_get_bpp16_depth(CirrusVGAState * s)
-{
- uint32_t ret = 16;
-
- switch (s->cirrus_hidden_dac_data & 0xf) {
- case 0:
- ret = 15;
- break; /* Sierra HiColor */
- case 1:
- ret = 16;
- break; /* XGA HiColor */
- default:
-#ifdef DEBUG_CIRRUS
- printf("cirrus: invalid DAC value %x in 16bpp\n",
- (s->cirrus_hidden_dac_data & 0xf));
-#endif
- ret = 15; /* XXX */
- break;
- }
- return ret;
-}
-
-static int cirrus_get_bpp(VGAState *s1)
-{
- CirrusVGAState * s = (CirrusVGAState *)s1;
- uint32_t ret = 8;
-
- if ((s->sr[0x07] & 0x01) != 0) {
- /* Cirrus SVGA */
- switch (s->sr[0x07] & CIRRUS_SR7_BPP_MASK) {
- case CIRRUS_SR7_BPP_8:
- ret = 8;
- break;
- case CIRRUS_SR7_BPP_16_DOUBLEVCLK:
- ret = cirrus_get_bpp16_depth(s);
- break;
- case CIRRUS_SR7_BPP_24:
- ret = 24;
- break;
- case CIRRUS_SR7_BPP_16:
- ret = cirrus_get_bpp16_depth(s);
- break;
- case CIRRUS_SR7_BPP_32:
- ret = 32;
- break;
- default:
-#ifdef DEBUG_CIRRUS
- printf("cirrus: unknown bpp - sr7=%x\n", s->sr[0x7]);
-#endif
- ret = 8;
- break;
- }
- } else {
- /* VGA */
- ret = 0;
- }
-
- return ret;
-}
-
-static void cirrus_get_resolution(VGAState *s, int *pwidth, int *pheight)
-{
- int width, height;
-
- width = (s->cr[0x01] + 1) * 8;
- height = s->cr[0x12] |
- ((s->cr[0x07] & 0x02) << 7) |
- ((s->cr[0x07] & 0x40) << 3);
- height = (height + 1);
- /* interlace support */
- if (s->cr[0x1a] & 0x01)
- height = height * 2;
- *pwidth = width;
- *pheight = height;
-}
-
-/***************************************
- *
- * bank memory
- *
- ***************************************/
-
-static void cirrus_update_bank_ptr(CirrusVGAState * s, unsigned bank_index)
-{
- unsigned offset;
- unsigned limit;
-
- if ((s->gr[0x0b] & 0x01) != 0) /* dual bank */
- offset = s->gr[0x09 + bank_index];
- else /* single bank */
- offset = s->gr[0x09];
-
- if ((s->gr[0x0b] & 0x20) != 0)
- offset <<= 14;
- else
- offset <<= 12;
-
- if (s->vram_size <= offset)
- limit = 0;
- else
- limit = s->vram_size - offset;
-
- if (((s->gr[0x0b] & 0x01) == 0) && (bank_index != 0)) {
- if (limit > 0x8000) {
- offset += 0x8000;
- limit -= 0x8000;
- } else {
- limit = 0;
- }
- }
-
- if (limit > 0) {
- s->cirrus_bank_base[bank_index] = offset;
- s->cirrus_bank_limit[bank_index] = limit;
- } else {
- s->cirrus_bank_base[bank_index] = 0;
- s->cirrus_bank_limit[bank_index] = 0;
- }
-}
-
-/***************************************
- *
- * I/O access between 0x3c4-0x3c5
- *
- ***************************************/
-
-static int
-cirrus_hook_read_sr(CirrusVGAState * s, unsigned reg_index, int *reg_value)
-{
- switch (reg_index) {
- case 0x00: // Standard VGA
- case 0x01: // Standard VGA
- case 0x02: // Standard VGA
- case 0x03: // Standard VGA
- case 0x04: // Standard VGA
- return CIRRUS_HOOK_NOT_HANDLED;
- case 0x06: // Unlock Cirrus extensions
- *reg_value = s->sr[reg_index];
- break;
- case 0x10:
- case 0x30:
- case 0x50:
- case 0x70: // Graphics Cursor X
- case 0x90:
- case 0xb0:
- case 0xd0:
- case 0xf0: // Graphics Cursor X
- *reg_value = s->sr[0x10];
- break;
- case 0x11:
- case 0x31:
- case 0x51:
- case 0x71: // Graphics Cursor Y
- case 0x91:
- case 0xb1:
- case 0xd1:
- case 0xf1: // Graphics Cursor Y
- *reg_value = s->sr[0x11];
- break;
- case 0x05: // ???
- case 0x07: // Extended Sequencer Mode
- case 0x08: // EEPROM Control
- case 0x09: // Scratch Register 0
- case 0x0a: // Scratch Register 1
- case 0x0b: // VCLK 0
- case 0x0c: // VCLK 1
- case 0x0d: // VCLK 2
- case 0x0e: // VCLK 3
- case 0x0f: // DRAM Control
- case 0x12: // Graphics Cursor Attribute
- case 0x13: // Graphics Cursor Pattern Address
- case 0x14: // Scratch Register 2
- case 0x15: // Scratch Register 3
- case 0x16: // Performance Tuning Register
- case 0x17: // Configuration Readback and Extended Control
- case 0x18: // Signature Generator Control
- case 0x19: // Signal Generator Result
- case 0x1a: // Signal Generator Result
- case 0x1b: // VCLK 0 Denominator & Post
- case 0x1c: // VCLK 1 Denominator & Post
- case 0x1d: // VCLK 2 Denominator & Post
- case 0x1e: // VCLK 3 Denominator & Post
- case 0x1f: // BIOS Write Enable and MCLK select
-#ifdef DEBUG_CIRRUS
- printf("cirrus: handled inport sr_index %02x\n", reg_index);
-#endif
- *reg_value = s->sr[reg_index];
- break;
- default:
-#ifdef DEBUG_CIRRUS
- printf("cirrus: inport sr_index %02x\n", reg_index);
-#endif
- *reg_value = 0xff;
- break;
- }
-
- return CIRRUS_HOOK_HANDLED;
-}
-
-static int
-cirrus_hook_write_sr(CirrusVGAState * s, unsigned reg_index, int reg_value)
-{
- switch (reg_index) {
- case 0x00: // Standard VGA
- case 0x01: // Standard VGA
- case 0x02: // Standard VGA
- case 0x03: // Standard VGA
- case 0x04: // Standard VGA
- return CIRRUS_HOOK_NOT_HANDLED;
- case 0x06: // Unlock Cirrus extensions
- reg_value &= 0x17;
- if (reg_value == 0x12) {
- s->sr[reg_index] = 0x12;
- } else {
- s->sr[reg_index] = 0x0f;
- }
- break;
- case 0x10:
- case 0x30:
- case 0x50:
- case 0x70: // Graphics Cursor X
- case 0x90:
- case 0xb0:
- case 0xd0:
- case 0xf0: // Graphics Cursor X
- s->sr[0x10] = reg_value;
- s->hw_cursor_x = (reg_value << 3) | (reg_index >> 5);
- break;
- case 0x11:
- case 0x31:
- case 0x51:
- case 0x71: // Graphics Cursor Y
- case 0x91:
- case 0xb1:
- case 0xd1:
- case 0xf1: // Graphics Cursor Y
- s->sr[0x11] = reg_value;
- s->hw_cursor_y = (reg_value << 3) | (reg_index >> 5);
- break;
- case 0x07: // Extended Sequencer Mode
- case 0x08: // EEPROM Control
- case 0x09: // Scratch Register 0
- case 0x0a: // Scratch Register 1
- case 0x0b: // VCLK 0
- case 0x0c: // VCLK 1
- case 0x0d: // VCLK 2
- case 0x0e: // VCLK 3
- case 0x0f: // DRAM Control
- case 0x12: // Graphics Cursor Attribute
- case 0x13: // Graphics Cursor Pattern Address
- case 0x14: // Scratch Register 2
- case 0x15: // Scratch Register 3
- case 0x16: // Performance Tuning Register
- case 0x18: // Signature Generator Control
- case 0x19: // Signature Generator Result
- case 0x1a: // Signature Generator Result
- case 0x1b: // VCLK 0 Denominator & Post
- case 0x1c: // VCLK 1 Denominator & Post
- case 0x1d: // VCLK 2 Denominator & Post
- case 0x1e: // VCLK 3 Denominator & Post
- case 0x1f: // BIOS Write Enable and MCLK select
- s->sr[reg_index] = reg_value;
-#ifdef DEBUG_CIRRUS
- printf("cirrus: handled outport sr_index %02x, sr_value %02x\n",
- reg_index, reg_value);
-#endif
- break;
- case 0x17: // Configuration Readback and Extended Control
- s->sr[reg_index] = reg_value;
- cirrus_update_memory_access(s);
- break;
- default:
-#ifdef DEBUG_CIRRUS
- printf("cirrus: outport sr_index %02x, sr_value %02x\n", reg_index,
- reg_value);
-#endif
- break;
- }
-
- return CIRRUS_HOOK_HANDLED;
-}
-
-/***************************************
- *
- * I/O access at 0x3c6
- *
- ***************************************/
-
-static void cirrus_read_hidden_dac(CirrusVGAState * s, int *reg_value)
-{
- *reg_value = 0xff;
- if (++s->cirrus_hidden_dac_lockindex == 5) {
- *reg_value = s->cirrus_hidden_dac_data;
- s->cirrus_hidden_dac_lockindex = 0;
- }
-}
-
-static void cirrus_write_hidden_dac(CirrusVGAState * s, int reg_value)
-{
- if (s->cirrus_hidden_dac_lockindex == 4) {
- s->cirrus_hidden_dac_data = reg_value;
-#if defined(DEBUG_CIRRUS)
- printf("cirrus: outport hidden DAC, value %02x\n", reg_value);
-#endif
- }
- s->cirrus_hidden_dac_lockindex = 0;
-}
-
-/***************************************
- *
- * I/O access at 0x3c9
- *
- ***************************************/
-
-static int cirrus_hook_read_palette(CirrusVGAState * s, int *reg_value)
-{
- if (!(s->sr[0x12] & CIRRUS_CURSOR_HIDDENPEL))
- return CIRRUS_HOOK_NOT_HANDLED;
- *reg_value =
- s->cirrus_hidden_palette[(s->dac_read_index & 0x0f) * 3 +
- s->dac_sub_index];
- if (++s->dac_sub_index == 3) {
- s->dac_sub_index = 0;
- s->dac_read_index++;
- }
- return CIRRUS_HOOK_HANDLED;
-}
-
-static int cirrus_hook_write_palette(CirrusVGAState * s, int reg_value)
-{
- if (!(s->sr[0x12] & CIRRUS_CURSOR_HIDDENPEL))
- return CIRRUS_HOOK_NOT_HANDLED;
- s->dac_cache[s->dac_sub_index] = reg_value;
- if (++s->dac_sub_index == 3) {
- memcpy(&s->cirrus_hidden_palette[(s->dac_write_index & 0x0f) * 3],
- s->dac_cache, 3);
- /* XXX update cursor */
- s->dac_sub_index = 0;
- s->dac_write_index++;
- }
- return CIRRUS_HOOK_HANDLED;
-}
-
-/***************************************
- *
- * I/O access between 0x3ce-0x3cf
- *
- ***************************************/
-
-static int
-cirrus_hook_read_gr(CirrusVGAState * s, unsigned reg_index, int *reg_value)
-{
- switch (reg_index) {
- case 0x00: // Standard VGA, BGCOLOR 0x000000ff
- *reg_value = s->cirrus_shadow_gr0;
- return CIRRUS_HOOK_HANDLED;
- case 0x01: // Standard VGA, FGCOLOR 0x000000ff
- *reg_value = s->cirrus_shadow_gr1;
- return CIRRUS_HOOK_HANDLED;
- case 0x02: // Standard VGA
- case 0x03: // Standard VGA
- case 0x04: // Standard VGA
- case 0x06: // Standard VGA
- case 0x07: // Standard VGA
- case 0x08: // Standard VGA
- return CIRRUS_HOOK_NOT_HANDLED;
- case 0x05: // Standard VGA, Cirrus extended mode
- default:
- break;
- }
-
- if (reg_index < 0x3a) {
- *reg_value = s->gr[reg_index];
- } else {
-#ifdef DEBUG_CIRRUS
- printf("cirrus: inport gr_index %02x\n", reg_index);
-#endif
- *reg_value = 0xff;
- }
-
- return CIRRUS_HOOK_HANDLED;
-}
-
-static int
-cirrus_hook_write_gr(CirrusVGAState * s, unsigned reg_index, int reg_value)
-{
-#if defined(DEBUG_BITBLT) && 0
- printf("gr%02x: %02x\n", reg_index, reg_value);
-#endif
- switch (reg_index) {
- case 0x00: // Standard VGA, BGCOLOR 0x000000ff
- s->cirrus_shadow_gr0 = reg_value;
- return CIRRUS_HOOK_NOT_HANDLED;
- case 0x01: // Standard VGA, FGCOLOR 0x000000ff
- s->cirrus_shadow_gr1 = reg_value;
- return CIRRUS_HOOK_NOT_HANDLED;
- case 0x02: // Standard VGA
- case 0x03: // Standard VGA
- case 0x04: // Standard VGA
- case 0x06: // Standard VGA
- case 0x07: // Standard VGA
- case 0x08: // Standard VGA
- return CIRRUS_HOOK_NOT_HANDLED;
- case 0x05: // Standard VGA, Cirrus extended mode
- s->gr[reg_index] = reg_value & 0x7f;
- cirrus_update_memory_access(s);
- break;
- case 0x09: // bank offset #0
- case 0x0A: // bank offset #1
- s->gr[reg_index] = reg_value;
- cirrus_update_bank_ptr(s, 0);
- cirrus_update_bank_ptr(s, 1);
- break;
- case 0x0B:
- s->gr[reg_index] = reg_value;
- cirrus_update_bank_ptr(s, 0);
- cirrus_update_bank_ptr(s, 1);
- cirrus_update_memory_access(s);
- break;
- case 0x10: // BGCOLOR 0x0000ff00
- case 0x11: // FGCOLOR 0x0000ff00
- case 0x12: // BGCOLOR 0x00ff0000
- case 0x13: // FGCOLOR 0x00ff0000
- case 0x14: // BGCOLOR 0xff000000
- case 0x15: // FGCOLOR 0xff000000
- case 0x20: // BLT WIDTH 0x0000ff
- case 0x22: // BLT HEIGHT 0x0000ff
- case 0x24: // BLT DEST PITCH 0x0000ff
- case 0x26: // BLT SRC PITCH 0x0000ff
- case 0x28: // BLT DEST ADDR 0x0000ff
- case 0x29: // BLT DEST ADDR 0x00ff00
- case 0x2c: // BLT SRC ADDR 0x0000ff
- case 0x2d: // BLT SRC ADDR 0x00ff00
- case 0x2f: // BLT WRITEMASK
- case 0x30: // BLT MODE
- case 0x32: // RASTER OP
- case 0x33: // BLT MODEEXT
- case 0x34: // BLT TRANSPARENT COLOR 0x00ff
- case 0x35: // BLT TRANSPARENT COLOR 0xff00
- case 0x38: // BLT TRANSPARENT COLOR MASK 0x00ff
- case 0x39: // BLT TRANSPARENT COLOR MASK 0xff00
- s->gr[reg_index] = reg_value;
- break;
- case 0x21: // BLT WIDTH 0x001f00
- case 0x23: // BLT HEIGHT 0x001f00
- case 0x25: // BLT DEST PITCH 0x001f00
- case 0x27: // BLT SRC PITCH 0x001f00
- s->gr[reg_index] = reg_value & 0x1f;
- break;
- case 0x2a: // BLT DEST ADDR 0x3f0000
- s->gr[reg_index] = reg_value & 0x3f;
- /* if auto start mode, starts bit blt now */
- if (s->gr[0x31] & CIRRUS_BLT_AUTOSTART) {
- cirrus_bitblt_start(s);
- }
- break;
- case 0x2e: // BLT SRC ADDR 0x3f0000
- s->gr[reg_index] = reg_value & 0x3f;
- break;
- case 0x31: // BLT STATUS/START
- cirrus_write_bitblt(s, reg_value);
- break;
- default:
-#ifdef DEBUG_CIRRUS
- printf("cirrus: outport gr_index %02x, gr_value %02x\n", reg_index,
- reg_value);
-#endif
- break;
- }
-
- return CIRRUS_HOOK_HANDLED;
-}
-
-/***************************************
- *
- * I/O access between 0x3d4-0x3d5
- *
- ***************************************/
-
-static int
-cirrus_hook_read_cr(CirrusVGAState * s, unsigned reg_index, int *reg_value)
-{
- switch (reg_index) {
- case 0x00: // Standard VGA
- case 0x01: // Standard VGA
- case 0x02: // Standard VGA
- case 0x03: // Standard VGA
- case 0x04: // Standard VGA
- case 0x05: // Standard VGA
- case 0x06: // Standard VGA
- case 0x07: // Standard VGA
- case 0x08: // Standard VGA
- case 0x09: // Standard VGA
- case 0x0a: // Standard VGA
- case 0x0b: // Standard VGA
- case 0x0c: // Standard VGA
- case 0x0d: // Standard VGA
- case 0x0e: // Standard VGA
- case 0x0f: // Standard VGA
- case 0x10: // Standard VGA
- case 0x11: // Standard VGA
- case 0x12: // Standard VGA
- case 0x13: // Standard VGA
- case 0x14: // Standard VGA
- case 0x15: // Standard VGA
- case 0x16: // Standard VGA
- case 0x17: // Standard VGA
- case 0x18: // Standard VGA
- return CIRRUS_HOOK_NOT_HANDLED;
- case 0x19: // Interlace End
- case 0x1a: // Miscellaneous Control
- case 0x1b: // Extended Display Control
- case 0x1c: // Sync Adjust and Genlock
- case 0x1d: // Overlay Extended Control
- case 0x22: // Graphics Data Latches Readback (R)
- case 0x24: // Attribute Controller Toggle Readback (R)
- case 0x25: // Part Status
- case 0x27: // Part ID (R)
- *reg_value = s->cr[reg_index];
- break;
- case 0x26: // Attribute Controller Index Readback (R)
- *reg_value = s->ar_index & 0x3f;
- break;
- default:
-#ifdef DEBUG_CIRRUS
- printf("cirrus: inport cr_index %02x\n", reg_index);
- *reg_value = 0xff;
-#endif
- break;
- }
-
- return CIRRUS_HOOK_HANDLED;
-}
-
-static int
-cirrus_hook_write_cr(CirrusVGAState * s, unsigned reg_index, int reg_value)
-{
- switch (reg_index) {
- case 0x00: // Standard VGA
- case 0x01: // Standard VGA
- case 0x02: // Standard VGA
- case 0x03: // Standard VGA
- case 0x04: // Standard VGA
- case 0x05: // Standard VGA
- case 0x06: // Standard VGA
- case 0x07: // Standard VGA
- case 0x08: // Standard VGA
- case 0x09: // Standard VGA
- case 0x0a: // Standard VGA
- case 0x0b: // Standard VGA
- case 0x0c: // Standard VGA
- case 0x0d: // Standard VGA
- case 0x0e: // Standard VGA
- case 0x0f: // Standard VGA
- case 0x10: // Standard VGA
- case 0x11: // Standard VGA
- case 0x12: // Standard VGA
- case 0x13: // Standard VGA
- case 0x14: // Standard VGA
- case 0x15: // Standard VGA
- case 0x16: // Standard VGA
- case 0x17: // Standard VGA
- case 0x18: // Standard VGA
- return CIRRUS_HOOK_NOT_HANDLED;
- case 0x19: // Interlace End
- case 0x1a: // Miscellaneous Control
- case 0x1b: // Extended Display Control
- case 0x1c: // Sync Adjust and Genlock
- case 0x1d: // Overlay Extended Control
- s->cr[reg_index] = reg_value;
-#ifdef DEBUG_CIRRUS
- printf("cirrus: handled outport cr_index %02x, cr_value %02x\n",
- reg_index, reg_value);
-#endif
- break;
- case 0x22: // Graphics Data Latches Readback (R)
- case 0x24: // Attribute Controller Toggle Readback (R)
- case 0x26: // Attribute Controller Index Readback (R)
- case 0x27: // Part ID (R)
- break;
- case 0x25: // Part Status
- default:
-#ifdef DEBUG_CIRRUS
- printf("cirrus: outport cr_index %02x, cr_value %02x\n", reg_index,
- reg_value);
-#endif
- break;
- }
-
- return CIRRUS_HOOK_HANDLED;
-}
-
-/***************************************
- *
- * memory-mapped I/O (bitblt)
- *
- ***************************************/
-
-static uint8_t cirrus_mmio_blt_read(CirrusVGAState * s, unsigned address)
-{
- int value = 0xff;
-
- switch (address) {
- case (CIRRUS_MMIO_BLTBGCOLOR + 0):
- cirrus_hook_read_gr(s, 0x00, &value);
- break;
- case (CIRRUS_MMIO_BLTBGCOLOR + 1):
- cirrus_hook_read_gr(s, 0x10, &value);
- break;
- case (CIRRUS_MMIO_BLTBGCOLOR + 2):
- cirrus_hook_read_gr(s, 0x12, &value);
- break;
- case (CIRRUS_MMIO_BLTBGCOLOR + 3):
- cirrus_hook_read_gr(s, 0x14, &value);
- break;
- case (CIRRUS_MMIO_BLTFGCOLOR + 0):
- cirrus_hook_read_gr(s, 0x01, &value);
- break;
- case (CIRRUS_MMIO_BLTFGCOLOR + 1):
- cirrus_hook_read_gr(s, 0x11, &value);
- break;
- case (CIRRUS_MMIO_BLTFGCOLOR + 2):
- cirrus_hook_read_gr(s, 0x13, &value);
- break;
- case (CIRRUS_MMIO_BLTFGCOLOR + 3):
- cirrus_hook_read_gr(s, 0x15, &value);
- break;
- case (CIRRUS_MMIO_BLTWIDTH + 0):
- cirrus_hook_read_gr(s, 0x20, &value);
- break;
- case (CIRRUS_MMIO_BLTWIDTH + 1):
- cirrus_hook_read_gr(s, 0x21, &value);
- break;
- case (CIRRUS_MMIO_BLTHEIGHT + 0):
- cirrus_hook_read_gr(s, 0x22, &value);
- break;
- case (CIRRUS_MMIO_BLTHEIGHT + 1):
- cirrus_hook_read_gr(s, 0x23, &value);
- break;
- case (CIRRUS_MMIO_BLTDESTPITCH + 0):
- cirrus_hook_read_gr(s, 0x24, &value);
- break;
- case (CIRRUS_MMIO_BLTDESTPITCH + 1):
- cirrus_hook_read_gr(s, 0x25, &value);
- break;
- case (CIRRUS_MMIO_BLTSRCPITCH + 0):
- cirrus_hook_read_gr(s, 0x26, &value);
- break;
- case (CIRRUS_MMIO_BLTSRCPITCH + 1):
- cirrus_hook_read_gr(s, 0x27, &value);
- break;
- case (CIRRUS_MMIO_BLTDESTADDR + 0):
- cirrus_hook_read_gr(s, 0x28, &value);
- break;
- case (CIRRUS_MMIO_BLTDESTADDR + 1):
- cirrus_hook_read_gr(s, 0x29, &value);
- break;
- case (CIRRUS_MMIO_BLTDESTADDR + 2):
- cirrus_hook_read_gr(s, 0x2a, &value);
- break;
- case (CIRRUS_MMIO_BLTSRCADDR + 0):
- cirrus_hook_read_gr(s, 0x2c, &value);
- break;
- case (CIRRUS_MMIO_BLTSRCADDR + 1):
- cirrus_hook_read_gr(s, 0x2d, &value);
- break;
- case (CIRRUS_MMIO_BLTSRCADDR + 2):
- cirrus_hook_read_gr(s, 0x2e, &value);
- break;
- case CIRRUS_MMIO_BLTWRITEMASK:
- cirrus_hook_read_gr(s, 0x2f, &value);
- break;
- case CIRRUS_MMIO_BLTMODE:
- cirrus_hook_read_gr(s, 0x30, &value);
- break;
- case CIRRUS_MMIO_BLTROP:
- cirrus_hook_read_gr(s, 0x32, &value);
- break;
- case CIRRUS_MMIO_BLTMODEEXT:
- cirrus_hook_read_gr(s, 0x33, &value);
- break;
- case (CIRRUS_MMIO_BLTTRANSPARENTCOLOR + 0):
- cirrus_hook_read_gr(s, 0x34, &value);
- break;
- case (CIRRUS_MMIO_BLTTRANSPARENTCOLOR + 1):
- cirrus_hook_read_gr(s, 0x35, &value);
- break;
- case (CIRRUS_MMIO_BLTTRANSPARENTCOLORMASK + 0):
- cirrus_hook_read_gr(s, 0x38, &value);
- break;
- case (CIRRUS_MMIO_BLTTRANSPARENTCOLORMASK + 1):
- cirrus_hook_read_gr(s, 0x39, &value);
- break;
- case CIRRUS_MMIO_BLTSTATUS:
- cirrus_hook_read_gr(s, 0x31, &value);
- break;
- default:
-#ifdef DEBUG_CIRRUS
- printf("cirrus: mmio read - address 0x%04x\n", address);
-#endif
- break;
- }
-
- return (uint8_t) value;
-}
-
-static void cirrus_mmio_blt_write(CirrusVGAState * s, unsigned address,
- uint8_t value)
-{
- switch (address) {
- case (CIRRUS_MMIO_BLTBGCOLOR + 0):
- cirrus_hook_write_gr(s, 0x00, value);
- break;
- case (CIRRUS_MMIO_BLTBGCOLOR + 1):
- cirrus_hook_write_gr(s, 0x10, value);
- break;
- case (CIRRUS_MMIO_BLTBGCOLOR + 2):
- cirrus_hook_write_gr(s, 0x12, value);
- break;
- case (CIRRUS_MMIO_BLTBGCOLOR + 3):
- cirrus_hook_write_gr(s, 0x14, value);
- break;
- case (CIRRUS_MMIO_BLTFGCOLOR + 0):
- cirrus_hook_write_gr(s, 0x01, value);
- break;
- case (CIRRUS_MMIO_BLTFGCOLOR + 1):
- cirrus_hook_write_gr(s, 0x11, value);
- break;
- case (CIRRUS_MMIO_BLTFGCOLOR + 2):
- cirrus_hook_write_gr(s, 0x13, value);
- break;
- case (CIRRUS_MMIO_BLTFGCOLOR + 3):
- cirrus_hook_write_gr(s, 0x15, value);
- break;
- case (CIRRUS_MMIO_BLTWIDTH + 0):
- cirrus_hook_write_gr(s, 0x20, value);
- break;
- case (CIRRUS_MMIO_BLTWIDTH + 1):
- cirrus_hook_write_gr(s, 0x21, value);
- break;
- case (CIRRUS_MMIO_BLTHEIGHT + 0):
- cirrus_hook_write_gr(s, 0x22, value);
- break;
- case (CIRRUS_MMIO_BLTHEIGHT + 1):
- cirrus_hook_write_gr(s, 0x23, value);
- break;
- case (CIRRUS_MMIO_BLTDESTPITCH + 0):
- cirrus_hook_write_gr(s, 0x24, value);
- break;
- case (CIRRUS_MMIO_BLTDESTPITCH + 1):
- cirrus_hook_write_gr(s, 0x25, value);
- break;
- case (CIRRUS_MMIO_BLTSRCPITCH + 0):
- cirrus_hook_write_gr(s, 0x26, value);
- break;
- case (CIRRUS_MMIO_BLTSRCPITCH + 1):
- cirrus_hook_write_gr(s, 0x27, value);
- break;
- case (CIRRUS_MMIO_BLTDESTADDR + 0):
- cirrus_hook_write_gr(s, 0x28, value);
- break;
- case (CIRRUS_MMIO_BLTDESTADDR + 1):
- cirrus_hook_write_gr(s, 0x29, value);
- break;
- case (CIRRUS_MMIO_BLTDESTADDR + 2):
- cirrus_hook_write_gr(s, 0x2a, value);
- break;
- case (CIRRUS_MMIO_BLTDESTADDR + 3):
- /* ignored */
- break;
- case (CIRRUS_MMIO_BLTSRCADDR + 0):
- cirrus_hook_write_gr(s, 0x2c, value);
- break;
- case (CIRRUS_MMIO_BLTSRCADDR + 1):
- cirrus_hook_write_gr(s, 0x2d, value);
- break;
- case (CIRRUS_MMIO_BLTSRCADDR + 2):
- cirrus_hook_write_gr(s, 0x2e, value);
- break;
- case CIRRUS_MMIO_BLTWRITEMASK:
- cirrus_hook_write_gr(s, 0x2f, value);
- break;
- case CIRRUS_MMIO_BLTMODE:
- cirrus_hook_write_gr(s, 0x30, value);
- break;
- case CIRRUS_MMIO_BLTROP:
- cirrus_hook_write_gr(s, 0x32, value);
- break;
- case CIRRUS_MMIO_BLTMODEEXT:
- cirrus_hook_write_gr(s, 0x33, value);
- break;
- case (CIRRUS_MMIO_BLTTRANSPARENTCOLOR + 0):
- cirrus_hook_write_gr(s, 0x34, value);
- break;
- case (CIRRUS_MMIO_BLTTRANSPARENTCOLOR + 1):
- cirrus_hook_write_gr(s, 0x35, value);
- break;
- case (CIRRUS_MMIO_BLTTRANSPARENTCOLORMASK + 0):
- cirrus_hook_write_gr(s, 0x38, value);
- break;
- case (CIRRUS_MMIO_BLTTRANSPARENTCOLORMASK + 1):
- cirrus_hook_write_gr(s, 0x39, value);
- break;
- case CIRRUS_MMIO_BLTSTATUS:
- cirrus_hook_write_gr(s, 0x31, value);
- break;
- default:
-#ifdef DEBUG_CIRRUS
- printf("cirrus: mmio write - addr 0x%04x val 0x%02x (ignored)\n",
- address, value);
-#endif
- break;
- }
-}
-
-/***************************************
- *
- * write mode 4/5
- *
- * assume TARGET_PAGE_SIZE >= 16
- *
- ***************************************/
-
-static void cirrus_mem_writeb_mode4and5_8bpp(CirrusVGAState * s,
- unsigned mode,
- unsigned offset,
- uint32_t mem_value)
-{
- int x;
- unsigned val = mem_value;
- uint8_t *dst;
-
- dst = s->vram_ptr + offset;
- for (x = 0; x < 8; x++) {
- if (val & 0x80) {
- *dst++ = s->cirrus_shadow_gr1;
- } else if (mode == 5) {
- *dst++ = s->cirrus_shadow_gr0;
- }
- val <<= 1;
- }
- cpu_physical_memory_set_dirty(s->vram_offset + offset);
- cpu_physical_memory_set_dirty(s->vram_offset + offset + 7);
-}
-
-static void cirrus_mem_writeb_mode4and5_16bpp(CirrusVGAState * s,
- unsigned mode,
- unsigned offset,
- uint32_t mem_value)
-{
- int x;
- unsigned val = mem_value;
- uint8_t *dst;
-
- dst = s->vram_ptr + offset;
- for (x = 0; x < 8; x++) {
- if (val & 0x80) {
- *dst++ = s->cirrus_shadow_gr1;
- *dst++ = s->gr[0x11];
- } else if (mode == 5) {
- *dst++ = s->cirrus_shadow_gr0;
- *dst++ = s->gr[0x10];
- }
- val <<= 1;
- }
- cpu_physical_memory_set_dirty(s->vram_offset + offset);
- cpu_physical_memory_set_dirty(s->vram_offset + offset + 15);
-}
-
-/***************************************
- *
- * memory access between 0xa0000-0xbffff
- *
- ***************************************/
-
-static uint32_t cirrus_vga_mem_readb(void *opaque, target_phys_addr_t addr)
-{
- CirrusVGAState *s = opaque;
- unsigned bank_index;
- unsigned bank_offset;
- uint32_t val;
-
- if ((s->sr[0x07] & 0x01) == 0) {
- return vga_mem_readb(s, addr);
- }
-
- addr &= 0x1ffff;
-
- if (addr < 0x10000) {
- /* XXX handle bitblt */
- /* video memory */
- bank_index = addr >> 15;
- bank_offset = addr & 0x7fff;
- if (bank_offset < s->cirrus_bank_limit[bank_index]) {
- bank_offset += s->cirrus_bank_base[bank_index];
- if ((s->gr[0x0B] & 0x14) == 0x14) {
- bank_offset <<= 4;
- } else if (s->gr[0x0B] & 0x02) {
- bank_offset <<= 3;
- }
- bank_offset &= s->cirrus_addr_mask;
- val = *(s->vram_ptr + bank_offset);
- } else
- val = 0xff;
- } else if (addr >= 0x18000 && addr < 0x18100) {
- /* memory-mapped I/O */
- val = 0xff;
- if ((s->sr[0x17] & 0x44) == 0x04) {
- val = cirrus_mmio_blt_read(s, addr & 0xff);
- }
- } else {
- val = 0xff;
-#ifdef DEBUG_CIRRUS
- printf("cirrus: mem_readb %06x\n", addr);
-#endif
- }
- return val;
-}
-
-static uint32_t cirrus_vga_mem_readw(void *opaque, target_phys_addr_t addr)
-{
- uint32_t v;
-#ifdef TARGET_WORDS_BIGENDIAN
- v = cirrus_vga_mem_readb(opaque, addr) << 8;
- v |= cirrus_vga_mem_readb(opaque, addr + 1);
-#else
- v = cirrus_vga_mem_readb(opaque, addr);
- v |= cirrus_vga_mem_readb(opaque, addr + 1) << 8;
-#endif
- return v;
-}
-
-static uint32_t cirrus_vga_mem_readl(void *opaque, target_phys_addr_t addr)
-{
- uint32_t v;
-#ifdef TARGET_WORDS_BIGENDIAN
- v = cirrus_vga_mem_readb(opaque, addr) << 24;
- v |= cirrus_vga_mem_readb(opaque, addr + 1) << 16;
- v |= cirrus_vga_mem_readb(opaque, addr + 2) << 8;
- v |= cirrus_vga_mem_readb(opaque, addr + 3);
-#else
- v = cirrus_vga_mem_readb(opaque, addr);
- v |= cirrus_vga_mem_readb(opaque, addr + 1) << 8;
- v |= cirrus_vga_mem_readb(opaque, addr + 2) << 16;
- v |= cirrus_vga_mem_readb(opaque, addr + 3) << 24;
-#endif
- return v;
-}
-
-static void cirrus_vga_mem_writeb(void *opaque, target_phys_addr_t addr,
- uint32_t mem_value)
-{
- CirrusVGAState *s = opaque;
- unsigned bank_index;
- unsigned bank_offset;
- unsigned mode;
-
- if ((s->sr[0x07] & 0x01) == 0) {
- vga_mem_writeb(s, addr, mem_value);
- return;
- }
-
- addr &= 0x1ffff;
-
- if (addr < 0x10000) {
- if (s->cirrus_srcptr != s->cirrus_srcptr_end) {
- /* bitblt */
- *s->cirrus_srcptr++ = (uint8_t) mem_value;
- if (s->cirrus_srcptr >= s->cirrus_srcptr_end) {
- cirrus_bitblt_cputovideo_next(s);
- }
- } else {
- /* video memory */
- bank_index = addr >> 15;
- bank_offset = addr & 0x7fff;
- if (bank_offset < s->cirrus_bank_limit[bank_index]) {
- bank_offset += s->cirrus_bank_base[bank_index];
- if ((s->gr[0x0B] & 0x14) == 0x14) {
- bank_offset <<= 4;
- } else if (s->gr[0x0B] & 0x02) {
- bank_offset <<= 3;
- }
- bank_offset &= s->cirrus_addr_mask;
- mode = s->gr[0x05] & 0x7;
- if (mode < 4 || mode > 5 || ((s->gr[0x0B] & 0x4) == 0)) {
- *(s->vram_ptr + bank_offset) = mem_value;
- cpu_physical_memory_set_dirty(s->vram_offset +
- bank_offset);
- } else {
- if ((s->gr[0x0B] & 0x14) != 0x14) {
- cirrus_mem_writeb_mode4and5_8bpp(s, mode,
- bank_offset,
- mem_value);
- } else {
- cirrus_mem_writeb_mode4and5_16bpp(s, mode,
- bank_offset,
- mem_value);
- }
- }
- }
- }
- } else if (addr >= 0x18000 && addr < 0x18100) {
- /* memory-mapped I/O */
- if ((s->sr[0x17] & 0x44) == 0x04) {
- cirrus_mmio_blt_write(s, addr & 0xff, mem_value);
- }
- } else {
-#ifdef DEBUG_CIRRUS
- printf("cirrus: mem_writeb %06x value %02x\n", addr, mem_value);
-#endif
- }
-}
-
-static void cirrus_vga_mem_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
-#ifdef TARGET_WORDS_BIGENDIAN
- cirrus_vga_mem_writeb(opaque, addr, (val >> 8) & 0xff);
- cirrus_vga_mem_writeb(opaque, addr + 1, val & 0xff);
-#else
- cirrus_vga_mem_writeb(opaque, addr, val & 0xff);
- cirrus_vga_mem_writeb(opaque, addr + 1, (val >> 8) & 0xff);
-#endif
-}
-
-static void cirrus_vga_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
-#ifdef TARGET_WORDS_BIGENDIAN
- cirrus_vga_mem_writeb(opaque, addr, (val >> 24) & 0xff);
- cirrus_vga_mem_writeb(opaque, addr + 1, (val >> 16) & 0xff);
- cirrus_vga_mem_writeb(opaque, addr + 2, (val >> 8) & 0xff);
- cirrus_vga_mem_writeb(opaque, addr + 3, val & 0xff);
-#else
- cirrus_vga_mem_writeb(opaque, addr, val & 0xff);
- cirrus_vga_mem_writeb(opaque, addr + 1, (val >> 8) & 0xff);
- cirrus_vga_mem_writeb(opaque, addr + 2, (val >> 16) & 0xff);
- cirrus_vga_mem_writeb(opaque, addr + 3, (val >> 24) & 0xff);
-#endif
-}
-
-static CPUReadMemoryFunc *cirrus_vga_mem_read[3] = {
- cirrus_vga_mem_readb,
- cirrus_vga_mem_readw,
- cirrus_vga_mem_readl,
-};
-
-static CPUWriteMemoryFunc *cirrus_vga_mem_write[3] = {
- cirrus_vga_mem_writeb,
- cirrus_vga_mem_writew,
- cirrus_vga_mem_writel,
-};
-
-/***************************************
- *
- * hardware cursor
- *
- ***************************************/
-
-static inline void invalidate_cursor1(CirrusVGAState *s)
-{
- if (s->last_hw_cursor_size) {
- vga_invalidate_scanlines((VGAState *)s,
- s->last_hw_cursor_y + s->last_hw_cursor_y_start,
- s->last_hw_cursor_y + s->last_hw_cursor_y_end);
- }
-}
-
-static inline void cirrus_cursor_compute_yrange(CirrusVGAState *s)
-{
- const uint8_t *src;
- uint32_t content;
- int y, y_min, y_max;
-
- src = s->vram_ptr + s->real_vram_size - 16 * 1024;
- if (s->sr[0x12] & CIRRUS_CURSOR_LARGE) {
- src += (s->sr[0x13] & 0x3c) * 256;
- y_min = 64;
- y_max = -1;
- for(y = 0; y < 64; y++) {
- content = ((uint32_t *)src)[0] |
- ((uint32_t *)src)[1] |
- ((uint32_t *)src)[2] |
- ((uint32_t *)src)[3];
- if (content) {
- if (y < y_min)
- y_min = y;
- if (y > y_max)
- y_max = y;
- }
- src += 16;
- }
- } else {
- src += (s->sr[0x13] & 0x3f) * 256;
- y_min = 32;
- y_max = -1;
- for(y = 0; y < 32; y++) {
- content = ((uint32_t *)src)[0] |
- ((uint32_t *)(src + 128))[0];
- if (content) {
- if (y < y_min)
- y_min = y;
- if (y > y_max)
- y_max = y;
- }
- src += 4;
- }
- }
- if (y_min > y_max) {
- s->last_hw_cursor_y_start = 0;
- s->last_hw_cursor_y_end = 0;
- } else {
- s->last_hw_cursor_y_start = y_min;
- s->last_hw_cursor_y_end = y_max + 1;
- }
-}
-
-/* NOTE: we do not currently handle the cursor bitmap change, so we
- update the cursor only if it moves. */
-static void cirrus_cursor_invalidate(VGAState *s1)
-{
- CirrusVGAState *s = (CirrusVGAState *)s1;
- int size;
-
- if (!s->sr[0x12] & CIRRUS_CURSOR_SHOW) {
- size = 0;
- } else {
- if (s->sr[0x12] & CIRRUS_CURSOR_LARGE)
- size = 64;
- else
- size = 32;
- }
- /* invalidate last cursor and new cursor if any change */
- if (s->last_hw_cursor_size != size ||
- s->last_hw_cursor_x != s->hw_cursor_x ||
- s->last_hw_cursor_y != s->hw_cursor_y) {
-
- invalidate_cursor1(s);
-
- s->last_hw_cursor_size = size;
- s->last_hw_cursor_x = s->hw_cursor_x;
- s->last_hw_cursor_y = s->hw_cursor_y;
- /* compute the real cursor min and max y */
- cirrus_cursor_compute_yrange(s);
- invalidate_cursor1(s);
- }
-}
-
-static void cirrus_cursor_draw_line(VGAState *s1, uint8_t *d1, int scr_y)
-{
- CirrusVGAState *s = (CirrusVGAState *)s1;
- int w, h, bpp, x1, x2, poffset;
- unsigned int color0, color1;
- const uint8_t *palette, *src;
- uint32_t content;
-
- if (!(s->sr[0x12] & CIRRUS_CURSOR_SHOW))
- return;
- /* fast test to see if the cursor intersects with the scan line */
- if (s->sr[0x12] & CIRRUS_CURSOR_LARGE) {
- h = 64;
- } else {
- h = 32;
- }
- if (scr_y < s->hw_cursor_y ||
- scr_y >= (s->hw_cursor_y + h))
- return;
-
- src = s->vram_ptr + s->real_vram_size - 16 * 1024;
- if (s->sr[0x12] & CIRRUS_CURSOR_LARGE) {
- src += (s->sr[0x13] & 0x3c) * 256;
- src += (scr_y - s->hw_cursor_y) * 16;
- poffset = 8;
- content = ((uint32_t *)src)[0] |
- ((uint32_t *)src)[1] |
- ((uint32_t *)src)[2] |
- ((uint32_t *)src)[3];
- } else {
- src += (s->sr[0x13] & 0x3f) * 256;
- src += (scr_y - s->hw_cursor_y) * 4;
- poffset = 128;
- content = ((uint32_t *)src)[0] |
- ((uint32_t *)(src + 128))[0];
- }
- /* if nothing to draw, no need to continue */
- if (!content)
- return;
- w = h;
-
- x1 = s->hw_cursor_x;
- if (x1 >= s->last_scr_width)
- return;
- x2 = s->hw_cursor_x + w;
- if (x2 > s->last_scr_width)
- x2 = s->last_scr_width;
- w = x2 - x1;
- palette = s->cirrus_hidden_palette;
- color0 = s->rgb_to_pixel(c6_to_8(palette[0x0 * 3]),
- c6_to_8(palette[0x0 * 3 + 1]),
- c6_to_8(palette[0x0 * 3 + 2]));
- color1 = s->rgb_to_pixel(c6_to_8(palette[0xf * 3]),
- c6_to_8(palette[0xf * 3 + 1]),
- c6_to_8(palette[0xf * 3 + 2]));
- bpp = ((s->ds->depth + 7) >> 3);
- d1 += x1 * bpp;
- switch(s->ds->depth) {
- default:
- break;
- case 8:
- vga_draw_cursor_line_8(d1, src, poffset, w, color0, color1, 0xff);
- break;
- case 15:
- vga_draw_cursor_line_16(d1, src, poffset, w, color0, color1, 0x7fff);
- break;
- case 16:
- vga_draw_cursor_line_16(d1, src, poffset, w, color0, color1, 0xffff);
- break;
- case 32:
- vga_draw_cursor_line_32(d1, src, poffset, w, color0, color1, 0xffffff);
- break;
- }
-}
-
-/***************************************
- *
- * LFB memory access
- *
- ***************************************/
-
-static uint32_t cirrus_linear_readb(void *opaque, target_phys_addr_t addr)
-{
- CirrusVGAState *s = (CirrusVGAState *) opaque;
- uint32_t ret;
-
- addr &= s->cirrus_addr_mask;
-
- if (((s->sr[0x17] & 0x44) == 0x44) &&
- ((addr & s->linear_mmio_mask) == s->linear_mmio_mask)) {
- /* memory-mapped I/O */
- ret = cirrus_mmio_blt_read(s, addr & 0xff);
- } else if (0) {
- /* XXX handle bitblt */
- ret = 0xff;
- } else {
- /* video memory */
- if ((s->gr[0x0B] & 0x14) == 0x14) {
- addr <<= 4;
- } else if (s->gr[0x0B] & 0x02) {
- addr <<= 3;
- }
- addr &= s->cirrus_addr_mask;
- ret = *(s->vram_ptr + addr);
- }
-
- return ret;
-}
-
-static uint32_t cirrus_linear_readw(void *opaque, target_phys_addr_t addr)
-{
- uint32_t v;
-#ifdef TARGET_WORDS_BIGENDIAN
- v = cirrus_linear_readb(opaque, addr) << 8;
- v |= cirrus_linear_readb(opaque, addr + 1);
-#else
- v = cirrus_linear_readb(opaque, addr);
- v |= cirrus_linear_readb(opaque, addr + 1) << 8;
-#endif
- return v;
-}
-
-static uint32_t cirrus_linear_readl(void *opaque, target_phys_addr_t addr)
-{
- uint32_t v;
-#ifdef TARGET_WORDS_BIGENDIAN
- v = cirrus_linear_readb(opaque, addr) << 24;
- v |= cirrus_linear_readb(opaque, addr + 1) << 16;
- v |= cirrus_linear_readb(opaque, addr + 2) << 8;
- v |= cirrus_linear_readb(opaque, addr + 3);
-#else
- v = cirrus_linear_readb(opaque, addr);
- v |= cirrus_linear_readb(opaque, addr + 1) << 8;
- v |= cirrus_linear_readb(opaque, addr + 2) << 16;
- v |= cirrus_linear_readb(opaque, addr + 3) << 24;
-#endif
- return v;
-}
-
-static void cirrus_linear_writeb(void *opaque, target_phys_addr_t addr,
- uint32_t val)
-{
- CirrusVGAState *s = (CirrusVGAState *) opaque;
- unsigned mode;
-
- addr &= s->cirrus_addr_mask;
-
- if (((s->sr[0x17] & 0x44) == 0x44) &&
- ((addr & s->linear_mmio_mask) == s->linear_mmio_mask)) {
- /* memory-mapped I/O */
- cirrus_mmio_blt_write(s, addr & 0xff, val);
- } else if (s->cirrus_srcptr != s->cirrus_srcptr_end) {
- /* bitblt */
- *s->cirrus_srcptr++ = (uint8_t) val;
- if (s->cirrus_srcptr >= s->cirrus_srcptr_end) {
- cirrus_bitblt_cputovideo_next(s);
- }
- } else {
- /* video memory */
- if ((s->gr[0x0B] & 0x14) == 0x14) {
- addr <<= 4;
- } else if (s->gr[0x0B] & 0x02) {
- addr <<= 3;
- }
- addr &= s->cirrus_addr_mask;
-
- mode = s->gr[0x05] & 0x7;
- if (mode < 4 || mode > 5 || ((s->gr[0x0B] & 0x4) == 0)) {
- *(s->vram_ptr + addr) = (uint8_t) val;
- cpu_physical_memory_set_dirty(s->vram_offset + addr);
- } else {
- if ((s->gr[0x0B] & 0x14) != 0x14) {
- cirrus_mem_writeb_mode4and5_8bpp(s, mode, addr, val);
- } else {
- cirrus_mem_writeb_mode4and5_16bpp(s, mode, addr, val);
- }
- }
- }
-}
-
-static void cirrus_linear_writew(void *opaque, target_phys_addr_t addr,
- uint32_t val)
-{
-#ifdef TARGET_WORDS_BIGENDIAN
- cirrus_linear_writeb(opaque, addr, (val >> 8) & 0xff);
- cirrus_linear_writeb(opaque, addr + 1, val & 0xff);
-#else
- cirrus_linear_writeb(opaque, addr, val & 0xff);
- cirrus_linear_writeb(opaque, addr + 1, (val >> 8) & 0xff);
-#endif
-}
-
-static void cirrus_linear_writel(void *opaque, target_phys_addr_t addr,
- uint32_t val)
-{
-#ifdef TARGET_WORDS_BIGENDIAN
- cirrus_linear_writeb(opaque, addr, (val >> 24) & 0xff);
- cirrus_linear_writeb(opaque, addr + 1, (val >> 16) & 0xff);
- cirrus_linear_writeb(opaque, addr + 2, (val >> 8) & 0xff);
- cirrus_linear_writeb(opaque, addr + 3, val & 0xff);
-#else
- cirrus_linear_writeb(opaque, addr, val & 0xff);
- cirrus_linear_writeb(opaque, addr + 1, (val >> 8) & 0xff);
- cirrus_linear_writeb(opaque, addr + 2, (val >> 16) & 0xff);
- cirrus_linear_writeb(opaque, addr + 3, (val >> 24) & 0xff);
-#endif
-}
-
-
-static CPUReadMemoryFunc *cirrus_linear_read[3] = {
- cirrus_linear_readb,
- cirrus_linear_readw,
- cirrus_linear_readl,
-};
-
-static CPUWriteMemoryFunc *cirrus_linear_write[3] = {
- cirrus_linear_writeb,
- cirrus_linear_writew,
- cirrus_linear_writel,
-};
-
-static void cirrus_linear_mem_writeb(void *opaque, target_phys_addr_t addr,
- uint32_t val)
-{
- CirrusVGAState *s = (CirrusVGAState *) opaque;
-
- addr &= s->cirrus_addr_mask;
- *(s->vram_ptr + addr) = val;
- cpu_physical_memory_set_dirty(s->vram_offset + addr);
-}
-
-static void cirrus_linear_mem_writew(void *opaque, target_phys_addr_t addr,
- uint32_t val)
-{
- CirrusVGAState *s = (CirrusVGAState *) opaque;
-
- addr &= s->cirrus_addr_mask;
- cpu_to_le16w((uint16_t *)(s->vram_ptr + addr), val);
- cpu_physical_memory_set_dirty(s->vram_offset + addr);
-}
-
-static void cirrus_linear_mem_writel(void *opaque, target_phys_addr_t addr,
- uint32_t val)
-{
- CirrusVGAState *s = (CirrusVGAState *) opaque;
-
- addr &= s->cirrus_addr_mask;
- cpu_to_le32w((uint32_t *)(s->vram_ptr + addr), val);
- cpu_physical_memory_set_dirty(s->vram_offset + addr);
-}
-
-/***************************************
- *
- * system to screen memory access
- *
- ***************************************/
-
-
-static uint32_t cirrus_linear_bitblt_readb(void *opaque, target_phys_addr_t addr)
-{
- uint32_t ret;
-
- /* XXX handle bitblt */
- ret = 0xff;
- return ret;
-}
-
-static uint32_t cirrus_linear_bitblt_readw(void *opaque, target_phys_addr_t addr)
-{
- uint32_t v;
-#ifdef TARGET_WORDS_BIGENDIAN
- v = cirrus_linear_bitblt_readb(opaque, addr) << 8;
- v |= cirrus_linear_bitblt_readb(opaque, addr + 1);
-#else
- v = cirrus_linear_bitblt_readb(opaque, addr);
- v |= cirrus_linear_bitblt_readb(opaque, addr + 1) << 8;
-#endif
- return v;
-}
-
-static uint32_t cirrus_linear_bitblt_readl(void *opaque, target_phys_addr_t addr)
-{
- uint32_t v;
-#ifdef TARGET_WORDS_BIGENDIAN
- v = cirrus_linear_bitblt_readb(opaque, addr) << 24;
- v |= cirrus_linear_bitblt_readb(opaque, addr + 1) << 16;
- v |= cirrus_linear_bitblt_readb(opaque, addr + 2) << 8;
- v |= cirrus_linear_bitblt_readb(opaque, addr + 3);
-#else
- v = cirrus_linear_bitblt_readb(opaque, addr);
- v |= cirrus_linear_bitblt_readb(opaque, addr + 1) << 8;
- v |= cirrus_linear_bitblt_readb(opaque, addr + 2) << 16;
- v |= cirrus_linear_bitblt_readb(opaque, addr + 3) << 24;
-#endif
- return v;
-}
-
-static void cirrus_linear_bitblt_writeb(void *opaque, target_phys_addr_t addr,
- uint32_t val)
-{
- CirrusVGAState *s = (CirrusVGAState *) opaque;
-
- if (s->cirrus_srcptr != s->cirrus_srcptr_end) {
- /* bitblt */
- *s->cirrus_srcptr++ = (uint8_t) val;
- if (s->cirrus_srcptr >= s->cirrus_srcptr_end) {
- cirrus_bitblt_cputovideo_next(s);
- }
- }
-}
-
-static void cirrus_linear_bitblt_writew(void *opaque, target_phys_addr_t addr,
- uint32_t val)
-{
-#ifdef TARGET_WORDS_BIGENDIAN
- cirrus_linear_bitblt_writeb(opaque, addr, (val >> 8) & 0xff);
- cirrus_linear_bitblt_writeb(opaque, addr + 1, val & 0xff);
-#else
- cirrus_linear_bitblt_writeb(opaque, addr, val & 0xff);
- cirrus_linear_bitblt_writeb(opaque, addr + 1, (val >> 8) & 0xff);
-#endif
-}
-
-static void cirrus_linear_bitblt_writel(void *opaque, target_phys_addr_t addr,
- uint32_t val)
-{
-#ifdef TARGET_WORDS_BIGENDIAN
- cirrus_linear_bitblt_writeb(opaque, addr, (val >> 24) & 0xff);
- cirrus_linear_bitblt_writeb(opaque, addr + 1, (val >> 16) & 0xff);
- cirrus_linear_bitblt_writeb(opaque, addr + 2, (val >> 8) & 0xff);
- cirrus_linear_bitblt_writeb(opaque, addr + 3, val & 0xff);
-#else
- cirrus_linear_bitblt_writeb(opaque, addr, val & 0xff);
- cirrus_linear_bitblt_writeb(opaque, addr + 1, (val >> 8) & 0xff);
- cirrus_linear_bitblt_writeb(opaque, addr + 2, (val >> 16) & 0xff);
- cirrus_linear_bitblt_writeb(opaque, addr + 3, (val >> 24) & 0xff);
-#endif
-}
-
-static CPUReadMemoryFunc *cirrus_linear_bitblt_read[3] = {
- cirrus_linear_bitblt_readb,
- cirrus_linear_bitblt_readw,
- cirrus_linear_bitblt_readl,
-};
-
-static CPUWriteMemoryFunc *cirrus_linear_bitblt_write[3] = {
- cirrus_linear_bitblt_writeb,
- cirrus_linear_bitblt_writew,
- cirrus_linear_bitblt_writel,
-};
-
-extern FILE *logfile;
-static void * set_vram_mapping(unsigned long begin, unsigned long end)
-{
- xen_pfn_t *extent_start = NULL;
- unsigned long nr_extents;
- void *vram_pointer = NULL;
- int i;
-
- /* align begin and end address */
- begin = begin & TARGET_PAGE_MASK;
- end = begin + VGA_RAM_SIZE;
- end = (end + TARGET_PAGE_SIZE -1 ) & TARGET_PAGE_MASK;
- nr_extents = (end - begin) >> TARGET_PAGE_BITS;
-
- extent_start = malloc(sizeof(xen_pfn_t) * nr_extents );
- if (extent_start == NULL)
- {
- fprintf(stderr, "Failed malloc on set_vram_mapping\n");
- return NULL;
- }
-
- memset(extent_start, 0, sizeof(xen_pfn_t) * nr_extents);
-
- for (i = 0; i < nr_extents; i++)
- {
- extent_start[i] = (begin + i * TARGET_PAGE_SIZE) >> TARGET_PAGE_BITS;
- }
-
- set_mm_mapping(xc_handle, domid, nr_extents, 0, extent_start);
-
- if ( (vram_pointer = xc_map_foreign_batch(xc_handle, domid,
- PROT_READ|PROT_WRITE,
- extent_start,
- nr_extents)) == NULL)
- {
- fprintf(logfile,
- "xc_map_foreign_batch vgaram returned error %d\n", errno);
- return NULL;
- }
-
- memset(vram_pointer, 0, nr_extents * TARGET_PAGE_SIZE);
-
- free(extent_start);
-
- return vram_pointer;
-}
-
-static int unset_vram_mapping(unsigned long begin, unsigned long end)
-{
- xen_pfn_t *extent_start = NULL;
- unsigned long nr_extents;
- int i;
-
- /* align begin and end address */
-
- end = begin + VGA_RAM_SIZE;
- begin = begin & TARGET_PAGE_MASK;
- end = (end + TARGET_PAGE_SIZE -1 ) & TARGET_PAGE_MASK;
- nr_extents = (end - begin) >> TARGET_PAGE_BITS;
-
- extent_start = malloc(sizeof(xen_pfn_t) * nr_extents );
-
- if (extent_start == NULL)
- {
- fprintf(stderr, "Failed malloc on set_mm_mapping\n");
- return -1;
- }
-
- memset(extent_start, 0, sizeof(xen_pfn_t) * nr_extents);
-
- for (i = 0; i < nr_extents; i++)
- extent_start[i] = (begin + (i * TARGET_PAGE_SIZE)) >> TARGET_PAGE_BITS;
-
- unset_mm_mapping(xc_handle, domid, nr_extents, 0, extent_start);
-
- free(extent_start);
-
- return 0;
-}
-
-extern int vga_accelerate;
-
-/* Compute the memory access functions */
-static void cirrus_update_memory_access(CirrusVGAState *s)
-{
- unsigned mode;
-
- if ((s->sr[0x17] & 0x44) == 0x44) {
- goto generic_io;
- } else if (s->cirrus_srcptr != s->cirrus_srcptr_end) {
- goto generic_io;
- } else {
- if ((s->gr[0x0B] & 0x14) == 0x14) {
- goto generic_io;
- } else if (s->gr[0x0B] & 0x02) {
- goto generic_io;
- }
-
- mode = s->gr[0x05] & 0x7;
- if (mode < 4 || mode > 5 || ((s->gr[0x0B] & 0x4) == 0)) {
- if ( vga_accelerate && s->cirrus_lfb_addr && s->cirrus_lfb_end ) {
- if (!s->map_addr) {
- void *vram_pointer, *old_vram;
-
- vram_pointer =
- set_vram_mapping(s->cirrus_lfb_addr ,s->cirrus_lfb_end);
- if (!vram_pointer) {
- fprintf(stderr, "NULL vram_pointer\n");
- } else {
- old_vram = vga_update_vram((VGAState *)s, vram_pointer,
- VGA_RAM_SIZE);
- qemu_free(old_vram);
- }
- s->map_addr = s->cirrus_lfb_addr;
- s->map_end = s->cirrus_lfb_end;
- }
- }
- s->cirrus_linear_write[0] = cirrus_linear_mem_writeb;
- s->cirrus_linear_write[1] = cirrus_linear_mem_writew;
- s->cirrus_linear_write[2] = cirrus_linear_mem_writel;
- } else {
- generic_io:
- if (vga_accelerate && s->cirrus_lfb_addr && s->cirrus_lfb_end) {
- if(s->map_addr) {
- int error;
- void *old_vram = NULL;
-
- error = unset_vram_mapping(s->cirrus_lfb_addr,
- s->cirrus_lfb_end);
- if (!error)
- old_vram =
- vga_update_vram((VGAState *)s, NULL, VGA_RAM_SIZE);
-
- if (old_vram)
- munmap(old_vram, s->map_addr - s->map_end);
- s->map_addr = s->map_end = 0;
- }
- }
-
- s->cirrus_linear_write[0] = cirrus_linear_writeb;
- s->cirrus_linear_write[1] = cirrus_linear_writew;
- s->cirrus_linear_write[2] = cirrus_linear_writel;
- }
- }
-}
-
-
-/* I/O ports */
-
-static uint32_t vga_ioport_read(void *opaque, uint32_t addr)
-{
- CirrusVGAState *s = opaque;
- int val, index;
-
- /* check port range access depending on color/monochrome mode */
- if ((addr >= 0x3b0 && addr <= 0x3bf && (s->msr & MSR_COLOR_EMULATION))
- || (addr >= 0x3d0 && addr <= 0x3df
- && !(s->msr & MSR_COLOR_EMULATION))) {
- val = 0xff;
- } else {
- switch (addr) {
- case 0x3c0:
- if (s->ar_flip_flop == 0) {
- val = s->ar_index;
- } else {
- val = 0;
- }
- break;
- case 0x3c1:
- index = s->ar_index & 0x1f;
- if (index < 21)
- val = s->ar[index];
- else
- val = 0;
- break;
- case 0x3c2:
- val = s->st00;
- break;
- case 0x3c4:
- val = s->sr_index;
- break;
- case 0x3c5:
- if (cirrus_hook_read_sr(s, s->sr_index, &val))
- break;
- val = s->sr[s->sr_index];
-#ifdef DEBUG_VGA_REG
- printf("vga: read SR%x = 0x%02x\n", s->sr_index, val);
-#endif
- break;
- case 0x3c6:
- cirrus_read_hidden_dac(s, &val);
- break;
- case 0x3c7:
- val = s->dac_state;
- break;
- case 0x3c8:
- val = s->dac_write_index;
- s->cirrus_hidden_dac_lockindex = 0;
- break;
- case 0x3c9:
- if (cirrus_hook_read_palette(s, &val))
- break;
- val = s->palette[s->dac_read_index * 3 + s->dac_sub_index];
- if (++s->dac_sub_index == 3) {
- s->dac_sub_index = 0;
- s->dac_read_index++;
- }
- break;
- case 0x3ca:
- val = s->fcr;
- break;
- case 0x3cc:
- val = s->msr;
- break;
- case 0x3ce:
- val = s->gr_index;
- break;
- case 0x3cf:
- if (cirrus_hook_read_gr(s, s->gr_index, &val))
- break;
- val = s->gr[s->gr_index];
-#ifdef DEBUG_VGA_REG
- printf("vga: read GR%x = 0x%02x\n", s->gr_index, val);
-#endif
- break;
- case 0x3b4:
- case 0x3d4:
- val = s->cr_index;
- break;
- case 0x3b5:
- case 0x3d5:
- if (cirrus_hook_read_cr(s, s->cr_index, &val))
- break;
- val = s->cr[s->cr_index];
-#ifdef DEBUG_VGA_REG
- printf("vga: read CR%x = 0x%02x\n", s->cr_index, val);
-#endif
- break;
- case 0x3ba:
- case 0x3da:
- /* just toggle to fool polling */
- s->st01 ^= ST01_V_RETRACE | ST01_DISP_ENABLE;
- val = s->st01;
- s->ar_flip_flop = 0;
- break;
- default:
- val = 0x00;
- break;
- }
- }
-#if defined(DEBUG_VGA)
- printf("VGA: read addr=0x%04x data=0x%02x\n", addr, val);
-#endif
- return val;
-}
-
-static void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val)
-{
- CirrusVGAState *s = opaque;
- int index;
-
- /* check port range access depending on color/monochrome mode */
- if ((addr >= 0x3b0 && addr <= 0x3bf && (s->msr & MSR_COLOR_EMULATION))
- || (addr >= 0x3d0 && addr <= 0x3df
- && !(s->msr & MSR_COLOR_EMULATION)))
- return;
-
-#ifdef DEBUG_VGA
- printf("VGA: write addr=0x%04x data=0x%02x\n", addr, val);
-#endif
-
- switch (addr) {
- case 0x3c0:
- if (s->ar_flip_flop == 0) {
- val &= 0x3f;
- s->ar_index = val;
- } else {
- index = s->ar_index & 0x1f;
- switch (index) {
- case 0x00 ... 0x0f:
- s->ar[index] = val & 0x3f;
- break;
- case 0x10:
- s->ar[index] = val & ~0x10;
- break;
- case 0x11:
- s->ar[index] = val;
- break;
- case 0x12:
- s->ar[index] = val & ~0xc0;
- break;
- case 0x13:
- s->ar[index] = val & ~0xf0;
- break;
- case 0x14:
- s->ar[index] = val & ~0xf0;
- break;
- default:
- break;
- }
- }
- s->ar_flip_flop ^= 1;
- break;
- case 0x3c2:
- s->msr = val & ~0x10;
- break;
- case 0x3c4:
- s->sr_index = val;
- break;
- case 0x3c5:
- if (cirrus_hook_write_sr(s, s->sr_index, val))
- break;
-#ifdef DEBUG_VGA_REG
- printf("vga: write SR%x = 0x%02x\n", s->sr_index, val);
-#endif
- s->sr[s->sr_index] = val & sr_mask[s->sr_index];
- break;
- case 0x3c6:
- cirrus_write_hidden_dac(s, val);
- break;
- case 0x3c7:
- s->dac_read_index = val;
- s->dac_sub_index = 0;
- s->dac_state = 3;
- break;
- case 0x3c8:
- s->dac_write_index = val;
- s->dac_sub_index = 0;
- s->dac_state = 0;
- break;
- case 0x3c9:
- if (cirrus_hook_write_palette(s, val))
- break;
- s->dac_cache[s->dac_sub_index] = val;
- if (++s->dac_sub_index == 3) {
- memcpy(&s->palette[s->dac_write_index * 3], s->dac_cache, 3);
- s->dac_sub_index = 0;
- s->dac_write_index++;
- }
- break;
- case 0x3ce:
- s->gr_index = val;
- break;
- case 0x3cf:
- if (cirrus_hook_write_gr(s, s->gr_index, val))
- break;
-#ifdef DEBUG_VGA_REG
- printf("vga: write GR%x = 0x%02x\n", s->gr_index, val);
-#endif
- s->gr[s->gr_index] = val & gr_mask[s->gr_index];
- break;
- case 0x3b4:
- case 0x3d4:
- s->cr_index = val;
- break;
- case 0x3b5:
- case 0x3d5:
- if (cirrus_hook_write_cr(s, s->cr_index, val))
- break;
-#ifdef DEBUG_VGA_REG
- printf("vga: write CR%x = 0x%02x\n", s->cr_index, val);
-#endif
- /* handle CR0-7 protection */
- if ((s->cr[0x11] & 0x80) && s->cr_index <= 7) {
- /* can always write bit 4 of CR7 */
- if (s->cr_index == 7)
- s->cr[7] = (s->cr[7] & ~0x10) | (val & 0x10);
- return;
- }
- switch (s->cr_index) {
- case 0x01: /* horizontal display end */
- case 0x07:
- case 0x09:
- case 0x0c:
- case 0x0d:
- case 0x12: /* veritcal display end */
- s->cr[s->cr_index] = val;
- break;
-
- default:
- s->cr[s->cr_index] = val;
- break;
- }
- break;
- case 0x3ba:
- case 0x3da:
- s->fcr = val & 0x10;
- break;
- }
-}
-
-/***************************************
- *
- * memory-mapped I/O access
- *
- ***************************************/
-
-static uint32_t cirrus_mmio_readb(void *opaque, target_phys_addr_t addr)
-{
- CirrusVGAState *s = (CirrusVGAState *) opaque;
-
- addr &= CIRRUS_PNPMMIO_SIZE - 1;
-
- if (addr >= 0x100) {
- return cirrus_mmio_blt_read(s, addr - 0x100);
- } else {
- return vga_ioport_read(s, addr + 0x3c0);
- }
-}
-
-static uint32_t cirrus_mmio_readw(void *opaque, target_phys_addr_t addr)
-{
- uint32_t v;
-#ifdef TARGET_WORDS_BIGENDIAN
- v = cirrus_mmio_readb(opaque, addr) << 8;
- v |= cirrus_mmio_readb(opaque, addr + 1);
-#else
- v = cirrus_mmio_readb(opaque, addr);
- v |= cirrus_mmio_readb(opaque, addr + 1) << 8;
-#endif
- return v;
-}
-
-static uint32_t cirrus_mmio_readl(void *opaque, target_phys_addr_t addr)
-{
- uint32_t v;
-#ifdef TARGET_WORDS_BIGENDIAN
- v = cirrus_mmio_readb(opaque, addr) << 24;
- v |= cirrus_mmio_readb(opaque, addr + 1) << 16;
- v |= cirrus_mmio_readb(opaque, addr + 2) << 8;
- v |= cirrus_mmio_readb(opaque, addr + 3);
-#else
- v = cirrus_mmio_readb(opaque, addr);
- v |= cirrus_mmio_readb(opaque, addr + 1) << 8;
- v |= cirrus_mmio_readb(opaque, addr + 2) << 16;
- v |= cirrus_mmio_readb(opaque, addr + 3) << 24;
-#endif
- return v;
-}
-
-static void cirrus_mmio_writeb(void *opaque, target_phys_addr_t addr,
- uint32_t val)
-{
- CirrusVGAState *s = (CirrusVGAState *) opaque;
-
- addr &= CIRRUS_PNPMMIO_SIZE - 1;
-
- if (addr >= 0x100) {
- cirrus_mmio_blt_write(s, addr - 0x100, val);
- } else {
- vga_ioport_write(s, addr + 0x3c0, val);
- }
-}
-
-static void cirrus_mmio_writew(void *opaque, target_phys_addr_t addr,
- uint32_t val)
-{
-#ifdef TARGET_WORDS_BIGENDIAN
- cirrus_mmio_writeb(opaque, addr, (val >> 8) & 0xff);
- cirrus_mmio_writeb(opaque, addr + 1, val & 0xff);
-#else
- cirrus_mmio_writeb(opaque, addr, val & 0xff);
- cirrus_mmio_writeb(opaque, addr + 1, (val >> 8) & 0xff);
-#endif
-}
-
-static void cirrus_mmio_writel(void *opaque, target_phys_addr_t addr,
- uint32_t val)
-{
-#ifdef TARGET_WORDS_BIGENDIAN
- cirrus_mmio_writeb(opaque, addr, (val >> 24) & 0xff);
- cirrus_mmio_writeb(opaque, addr + 1, (val >> 16) & 0xff);
- cirrus_mmio_writeb(opaque, addr + 2, (val >> 8) & 0xff);
- cirrus_mmio_writeb(opaque, addr + 3, val & 0xff);
-#else
- cirrus_mmio_writeb(opaque, addr, val & 0xff);
- cirrus_mmio_writeb(opaque, addr + 1, (val >> 8) & 0xff);
- cirrus_mmio_writeb(opaque, addr + 2, (val >> 16) & 0xff);
- cirrus_mmio_writeb(opaque, addr + 3, (val >> 24) & 0xff);
-#endif
-}
-
-
-static CPUReadMemoryFunc *cirrus_mmio_read[3] = {
- cirrus_mmio_readb,
- cirrus_mmio_readw,
- cirrus_mmio_readl,
-};
-
-static CPUWriteMemoryFunc *cirrus_mmio_write[3] = {
- cirrus_mmio_writeb,
- cirrus_mmio_writew,
- cirrus_mmio_writel,
-};
-
-/* load/save state */
-
-static void cirrus_vga_save(QEMUFile *f, void *opaque)
-{
- CirrusVGAState *s = opaque;
-
- qemu_put_be32s(f, &s->latch);
- qemu_put_8s(f, &s->sr_index);
- qemu_put_buffer(f, s->sr, 256);
- qemu_put_8s(f, &s->gr_index);
- qemu_put_8s(f, &s->cirrus_shadow_gr0);
- qemu_put_8s(f, &s->cirrus_shadow_gr1);
- qemu_put_buffer(f, s->gr + 2, 254);
- qemu_put_8s(f, &s->ar_index);
- qemu_put_buffer(f, s->ar, 21);
- qemu_put_be32s(f, &s->ar_flip_flop);
- qemu_put_8s(f, &s->cr_index);
- qemu_put_buffer(f, s->cr, 256);
- qemu_put_8s(f, &s->msr);
- qemu_put_8s(f, &s->fcr);
- qemu_put_8s(f, &s->st00);
- qemu_put_8s(f, &s->st01);
-
- qemu_put_8s(f, &s->dac_state);
- qemu_put_8s(f, &s->dac_sub_index);
- qemu_put_8s(f, &s->dac_read_index);
- qemu_put_8s(f, &s->dac_write_index);
- qemu_put_buffer(f, s->dac_cache, 3);
- qemu_put_buffer(f, s->palette, 768);
-
- qemu_put_be32s(f, &s->bank_offset);
-
- qemu_put_8s(f, &s->cirrus_hidden_dac_lockindex);
- qemu_put_8s(f, &s->cirrus_hidden_dac_data);
-
- qemu_put_be32s(f, &s->hw_cursor_x);
- qemu_put_be32s(f, &s->hw_cursor_y);
- /* XXX: we do not save the bitblt state - we assume we do not save
- the state when the blitter is active */
-}
-
-static int cirrus_vga_load(QEMUFile *f, void *opaque, int version_id)
-{
- CirrusVGAState *s = opaque;
-
- if (version_id != 1)
- return -EINVAL;
-
- qemu_get_be32s(f, &s->latch);
- qemu_get_8s(f, &s->sr_index);
- qemu_get_buffer(f, s->sr, 256);
- qemu_get_8s(f, &s->gr_index);
- qemu_get_8s(f, &s->cirrus_shadow_gr0);
- qemu_get_8s(f, &s->cirrus_shadow_gr1);
- s->gr[0x00] = s->cirrus_shadow_gr0 & 0x0f;
- s->gr[0x01] = s->cirrus_shadow_gr1 & 0x0f;
- qemu_get_buffer(f, s->gr + 2, 254);
- qemu_get_8s(f, &s->ar_index);
- qemu_get_buffer(f, s->ar, 21);
- qemu_get_be32s(f, &s->ar_flip_flop);
- qemu_get_8s(f, &s->cr_index);
- qemu_get_buffer(f, s->cr, 256);
- qemu_get_8s(f, &s->msr);
- qemu_get_8s(f, &s->fcr);
- qemu_get_8s(f, &s->st00);
- qemu_get_8s(f, &s->st01);
-
- qemu_get_8s(f, &s->dac_state);
- qemu_get_8s(f, &s->dac_sub_index);
- qemu_get_8s(f, &s->dac_read_index);
- qemu_get_8s(f, &s->dac_write_index);
- qemu_get_buffer(f, s->dac_cache, 3);
- qemu_get_buffer(f, s->palette, 768);
-
- qemu_get_be32s(f, &s->bank_offset);
-
- qemu_get_8s(f, &s->cirrus_hidden_dac_lockindex);
- qemu_get_8s(f, &s->cirrus_hidden_dac_data);
-
- qemu_get_be32s(f, &s->hw_cursor_x);
- qemu_get_be32s(f, &s->hw_cursor_y);
-
- /* force refresh */
- s->graphic_mode = -1;
- cirrus_update_bank_ptr(s, 0);
- cirrus_update_bank_ptr(s, 1);
- return 0;
-}
-
-/***************************************
- *
- * initialize
- *
- ***************************************/
-
-static void cirrus_init_common(CirrusVGAState * s, int device_id, int is_pci)
-{
- int vga_io_memory, i;
- static int inited;
-
- if (!inited) {
- inited = 1;
- for(i = 0;i < 256; i++)
- rop_to_index[i] = CIRRUS_ROP_NOP_INDEX; /* nop rop */
- rop_to_index[CIRRUS_ROP_0] = 0;
- rop_to_index[CIRRUS_ROP_SRC_AND_DST] = 1;
- rop_to_index[CIRRUS_ROP_NOP] = 2;
- rop_to_index[CIRRUS_ROP_SRC_AND_NOTDST] = 3;
- rop_to_index[CIRRUS_ROP_NOTDST] = 4;
- rop_to_index[CIRRUS_ROP_SRC] = 5;
- rop_to_index[CIRRUS_ROP_1] = 6;
- rop_to_index[CIRRUS_ROP_NOTSRC_AND_DST] = 7;
- rop_to_index[CIRRUS_ROP_SRC_XOR_DST] = 8;
- rop_to_index[CIRRUS_ROP_SRC_OR_DST] = 9;
- rop_to_index[CIRRUS_ROP_NOTSRC_OR_NOTDST] = 10;
- rop_to_index[CIRRUS_ROP_SRC_NOTXOR_DST] = 11;
- rop_to_index[CIRRUS_ROP_SRC_OR_NOTDST] = 12;
- rop_to_index[CIRRUS_ROP_NOTSRC] = 13;
- rop_to_index[CIRRUS_ROP_NOTSRC_OR_DST] = 14;
- rop_to_index[CIRRUS_ROP_NOTSRC_AND_NOTDST] = 15;
- }
-
- register_ioport_write(0x3c0, 16, 1, vga_ioport_write, s);
-
- register_ioport_write(0x3b4, 2, 1, vga_ioport_write, s);
- register_ioport_write(0x3d4, 2, 1, vga_ioport_write, s);
- register_ioport_write(0x3ba, 1, 1, vga_ioport_write, s);
- register_ioport_write(0x3da, 1, 1, vga_ioport_write, s);
-
- register_ioport_read(0x3c0, 16, 1, vga_ioport_read, s);
-
- register_ioport_read(0x3b4, 2, 1, vga_ioport_read, s);
- register_ioport_read(0x3d4, 2, 1, vga_ioport_read, s);
- register_ioport_read(0x3ba, 1, 1, vga_ioport_read, s);
- register_ioport_read(0x3da, 1, 1, vga_ioport_read, s);
-
- vga_io_memory = cpu_register_io_memory(0, cirrus_vga_mem_read,
- cirrus_vga_mem_write, s);
- cpu_register_physical_memory(isa_mem_base + 0x000a0000, 0x20000,
- vga_io_memory);
-
- s->sr[0x06] = 0x0f;
- if (device_id == CIRRUS_ID_CLGD5446) {
- /* 4MB 64 bit memory config, always PCI */
- s->sr[0x1F] = 0x2d; // MemClock
- s->gr[0x18] = 0x0f; // fastest memory configuration
-#if 1
- s->sr[0x0f] = 0x98;
- s->sr[0x17] = 0x20;
- s->sr[0x15] = 0x04; /* memory size, 3=2MB, 4=4MB */
- s->real_vram_size = 4096 * 1024;
-#else
- s->sr[0x0f] = 0x18;
- s->sr[0x17] = 0x20;
- s->sr[0x15] = 0x03; /* memory size, 3=2MB, 4=4MB */
- s->real_vram_size = 2048 * 1024;
-#endif
- } else {
- s->sr[0x1F] = 0x22; // MemClock
- s->sr[0x0F] = CIRRUS_MEMSIZE_2M;
- if (is_pci)
- s->sr[0x17] = CIRRUS_BUSTYPE_PCI;
- else
- s->sr[0x17] = CIRRUS_BUSTYPE_ISA;
- s->real_vram_size = 2048 * 1024;
- s->sr[0x15] = 0x03; /* memory size, 3=2MB, 4=4MB */
- }
- s->cr[0x27] = device_id;
-
- s->cirrus_hidden_dac_lockindex = 5;
- s->cirrus_hidden_dac_data = 0;
-
- /* I/O handler for LFB */
- s->cirrus_linear_io_addr =
- cpu_register_io_memory(0, cirrus_linear_read, cirrus_linear_write,
- s);
- s->cirrus_linear_write = cpu_get_io_memory_write(s->cirrus_linear_io_addr);
-
- /* I/O handler for LFB */
- s->cirrus_linear_bitblt_io_addr =
- cpu_register_io_memory(0, cirrus_linear_bitblt_read, cirrus_linear_bitblt_write,
- s);
-
- /* I/O handler for memory-mapped I/O */
- s->cirrus_mmio_io_addr =
- cpu_register_io_memory(0, cirrus_mmio_read, cirrus_mmio_write, s);
-
- /* XXX: s->vram_size must be a power of two */
- s->cirrus_addr_mask = s->real_vram_size - 1;
- s->linear_mmio_mask = s->real_vram_size - 256;
-
- s->get_bpp = cirrus_get_bpp;
- s->get_offsets = cirrus_get_offsets;
- s->get_resolution = cirrus_get_resolution;
- s->cursor_invalidate = cirrus_cursor_invalidate;
- s->cursor_draw_line = cirrus_cursor_draw_line;
-
- register_savevm("cirrus_vga", 0, 1, cirrus_vga_save, cirrus_vga_load, s);
-}
-
-/***************************************
- *
- * ISA bus support
- *
- ***************************************/
-
-void isa_cirrus_vga_init(DisplayState *ds, uint8_t *vga_ram_base,
- unsigned long vga_ram_offset, int vga_ram_size)
-{
- CirrusVGAState *s;
-
- s = qemu_mallocz(sizeof(CirrusVGAState));
-
- vga_common_init((VGAState *)s,
- ds, vga_ram_base, vga_ram_offset, vga_ram_size);
- cirrus_init_common(s, CIRRUS_ID_CLGD5430, 0);
- /* XXX ISA-LFB support */
-}
-
-/***************************************
- *
- * PCI bus support
- *
- ***************************************/
-
-static void cirrus_pci_lfb_map(PCIDevice *d, int region_num,
- uint32_t addr, uint32_t size, int type)
-{
- CirrusVGAState *s = &((PCICirrusVGAState *)d)->cirrus_vga;
-
- /* XXX: add byte swapping apertures */
- cpu_register_physical_memory(addr, s->vram_size,
- s->cirrus_linear_io_addr);
- s->cirrus_lfb_addr = addr;
- s->cirrus_lfb_end = addr + VGA_RAM_SIZE;
-
- if ( vga_accelerate && s->map_addr &&
- (s->cirrus_lfb_addr != s->map_addr) &&
- (s->cirrus_lfb_end != s->map_end))
- fprintf(logfile, "cirrus vga map change while on lfb mode\n");
-
- cpu_register_physical_memory(addr + 0x1000000, 0x400000,
- s->cirrus_linear_bitblt_io_addr);
-}
-
-static void cirrus_pci_mmio_map(PCIDevice *d, int region_num,
- uint32_t addr, uint32_t size, int type)
-{
- CirrusVGAState *s = &((PCICirrusVGAState *)d)->cirrus_vga;
-
- cpu_register_physical_memory(addr, CIRRUS_PNPMMIO_SIZE,
- s->cirrus_mmio_io_addr);
-}
-
-void pci_cirrus_vga_init(PCIBus *bus, DisplayState *ds, uint8_t *vga_ram_base,
- unsigned long vga_ram_offset, int vga_ram_size)
-{
- PCICirrusVGAState *d;
- uint8_t *pci_conf;
- CirrusVGAState *s;
- int device_id;
-
- device_id = CIRRUS_ID_CLGD5446;
-
- /* setup PCI configuration registers */
- d = (PCICirrusVGAState *)pci_register_device(bus, "Cirrus VGA",
- sizeof(PCICirrusVGAState),
- -1, NULL, NULL);
- pci_conf = d->dev.config;
- pci_conf[0x00] = (uint8_t) (PCI_VENDOR_CIRRUS & 0xff);
- pci_conf[0x01] = (uint8_t) (PCI_VENDOR_CIRRUS >> 8);
- pci_conf[0x02] = (uint8_t) (device_id & 0xff);
- pci_conf[0x03] = (uint8_t) (device_id >> 8);
- pci_conf[0x04] = PCI_COMMAND_IOACCESS | PCI_COMMAND_MEMACCESS;
- pci_conf[0x0a] = PCI_CLASS_SUB_VGA;
- pci_conf[0x0b] = PCI_CLASS_BASE_DISPLAY;
- pci_conf[0x0e] = PCI_CLASS_HEADERTYPE_00h;
-
- /* setup VGA */
- s = &d->cirrus_vga;
- vga_common_init((VGAState *)s,
- ds, vga_ram_base, vga_ram_offset, vga_ram_size);
- cirrus_init_common(s, device_id, 1);
-
- /* setup memory space */
- /* memory #0 LFB */
- /* memory #1 memory-mapped I/O */
- /* XXX: s->vram_size must be a power of two */
- pci_register_io_region((PCIDevice *)d, 0, 0x2000000,
- PCI_ADDRESS_SPACE_MEM_PREFETCH, cirrus_pci_lfb_map);
- if (device_id == CIRRUS_ID_CLGD5446) {
- pci_register_io_region((PCIDevice *)d, 1, CIRRUS_PNPMMIO_SIZE,
- PCI_ADDRESS_SPACE_MEM, cirrus_pci_mmio_map);
- }
- /* XXX: ROM BIOS */
-}
+++ /dev/null
-/*
- * QEMU Cirrus CLGD 54xx VGA Emulator.
- *
- * Copyright (c) 2004 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-static void
-glue(cirrus_bitblt_rop_fwd_, ROP_NAME)(CirrusVGAState *s,
- uint8_t *dst,const uint8_t *src,
- int dstpitch,int srcpitch,
- int bltwidth,int bltheight)
-{
- int x,y;
- dstpitch -= bltwidth;
- srcpitch -= bltwidth;
- for (y = 0; y < bltheight; y++) {
- for (x = 0; x < bltwidth; x++) {
- ROP_OP(*dst, *src);
- dst++;
- src++;
- }
- dst += dstpitch;
- src += srcpitch;
- }
-}
-
-static void
-glue(cirrus_bitblt_rop_bkwd_, ROP_NAME)(CirrusVGAState *s,
- uint8_t *dst,const uint8_t *src,
- int dstpitch,int srcpitch,
- int bltwidth,int bltheight)
-{
- int x,y;
- dstpitch += bltwidth;
- srcpitch += bltwidth;
- for (y = 0; y < bltheight; y++) {
- for (x = 0; x < bltwidth; x++) {
- ROP_OP(*dst, *src);
- dst--;
- src--;
- }
- dst += dstpitch;
- src += srcpitch;
- }
-}
-
-#define DEPTH 8
-#include "cirrus_vga_rop2.h"
-
-#define DEPTH 16
-#include "cirrus_vga_rop2.h"
-
-#define DEPTH 24
-#include "cirrus_vga_rop2.h"
-
-#define DEPTH 32
-#include "cirrus_vga_rop2.h"
-
-#undef ROP_NAME
-#undef ROP_OP
+++ /dev/null
-/*
- * QEMU Cirrus CLGD 54xx VGA Emulator.
- *
- * Copyright (c) 2004 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#if DEPTH == 8
-#define PUTPIXEL() ROP_OP(d[0], col)
-#elif DEPTH == 16
-#define PUTPIXEL() ROP_OP(((uint16_t *)d)[0], col);
-#elif DEPTH == 24
-#define PUTPIXEL() ROP_OP(d[0], col); \
- ROP_OP(d[1], (col >> 8)); \
- ROP_OP(d[2], (col >> 16))
-#elif DEPTH == 32
-#define PUTPIXEL() ROP_OP(((uint32_t *)d)[0], col)
-#else
-#error unsupported DEPTH
-#endif
-
-static void
-glue(glue(glue(cirrus_patternfill_, ROP_NAME), _),DEPTH)
- (CirrusVGAState * s, uint8_t * dst,
- const uint8_t * src,
- int dstpitch, int srcpitch,
- int bltwidth, int bltheight)
-{
- uint8_t *d;
- int x, y, pattern_y, pattern_pitch, pattern_x;
- unsigned int col;
- const uint8_t *src1;
-#if DEPTH == 24
- int skipleft = s->gr[0x2f] & 0x1f;
-#else
- int skipleft = (s->gr[0x2f] & 0x07) * (DEPTH / 8);
-#endif
-
-#if DEPTH == 8
- pattern_pitch = 8;
-#elif DEPTH == 16
- pattern_pitch = 16;
-#else
- pattern_pitch = 32;
-#endif
- pattern_y = s->cirrus_blt_srcaddr & 7;
- for(y = 0; y < bltheight; y++) {
- pattern_x = skipleft;
- d = dst + skipleft;
- src1 = src + pattern_y * pattern_pitch;
- for (x = skipleft; x < bltwidth; x += (DEPTH / 8)) {
-#if DEPTH == 8
- col = src1[pattern_x];
- pattern_x = (pattern_x + 1) & 7;
-#elif DEPTH == 16
- col = ((uint16_t *)(src1 + pattern_x))[0];
- pattern_x = (pattern_x + 2) & 15;
-#elif DEPTH == 24
- {
- const uint8_t *src2 = src1 + pattern_x * 3;
- col = src2[0] | (src2[1] << 8) | (src2[2] << 16);
- pattern_x = (pattern_x + 1) & 7;
- }
-#else
- col = ((uint32_t *)(src1 + pattern_x))[0];
- pattern_x = (pattern_x + 4) & 31;
-#endif
- PUTPIXEL();
- d += (DEPTH / 8);
- }
- pattern_y = (pattern_y + 1) & 7;
- dst += dstpitch;
- }
-}
-
-/* NOTE: srcpitch is ignored */
-static void
-glue(glue(glue(cirrus_colorexpand_transp_, ROP_NAME), _),DEPTH)
- (CirrusVGAState * s, uint8_t * dst,
- const uint8_t * src,
- int dstpitch, int srcpitch,
- int bltwidth, int bltheight)
-{
- uint8_t *d;
- int x, y;
- unsigned bits, bits_xor;
- unsigned int col;
- unsigned bitmask;
- unsigned index;
-#if DEPTH == 24
- int dstskipleft = s->gr[0x2f] & 0x1f;
- int srcskipleft = dstskipleft / 3;
-#else
- int srcskipleft = s->gr[0x2f] & 0x07;
- int dstskipleft = srcskipleft * (DEPTH / 8);
-#endif
-
- if (s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_COLOREXPINV) {
- bits_xor = 0xff;
- col = s->cirrus_blt_bgcol;
- } else {
- bits_xor = 0x00;
- col = s->cirrus_blt_fgcol;
- }
-
- for(y = 0; y < bltheight; y++) {
- bitmask = 0x80 >> srcskipleft;
- bits = *src++ ^ bits_xor;
- d = dst + dstskipleft;
- for (x = dstskipleft; x < bltwidth; x += (DEPTH / 8)) {
- if ((bitmask & 0xff) == 0) {
- bitmask = 0x80;
- bits = *src++ ^ bits_xor;
- }
- index = (bits & bitmask);
- if (index) {
- PUTPIXEL();
- }
- d += (DEPTH / 8);
- bitmask >>= 1;
- }
- dst += dstpitch;
- }
-}
-
-static void
-glue(glue(glue(cirrus_colorexpand_, ROP_NAME), _),DEPTH)
- (CirrusVGAState * s, uint8_t * dst,
- const uint8_t * src,
- int dstpitch, int srcpitch,
- int bltwidth, int bltheight)
-{
- uint32_t colors[2];
- uint8_t *d;
- int x, y;
- unsigned bits;
- unsigned int col;
- unsigned bitmask;
- int srcskipleft = s->gr[0x2f] & 0x07;
- int dstskipleft = srcskipleft * (DEPTH / 8);
-
- colors[0] = s->cirrus_blt_bgcol;
- colors[1] = s->cirrus_blt_fgcol;
- for(y = 0; y < bltheight; y++) {
- bitmask = 0x80 >> srcskipleft;
- bits = *src++;
- d = dst + dstskipleft;
- for (x = dstskipleft; x < bltwidth; x += (DEPTH / 8)) {
- if ((bitmask & 0xff) == 0) {
- bitmask = 0x80;
- bits = *src++;
- }
- col = colors[!!(bits & bitmask)];
- PUTPIXEL();
- d += (DEPTH / 8);
- bitmask >>= 1;
- }
- dst += dstpitch;
- }
-}
-
-static void
-glue(glue(glue(cirrus_colorexpand_pattern_transp_, ROP_NAME), _),DEPTH)
- (CirrusVGAState * s, uint8_t * dst,
- const uint8_t * src,
- int dstpitch, int srcpitch,
- int bltwidth, int bltheight)
-{
- uint8_t *d;
- int x, y, bitpos, pattern_y;
- unsigned int bits, bits_xor;
- unsigned int col;
-#if DEPTH == 24
- int dstskipleft = s->gr[0x2f] & 0x1f;
- int srcskipleft = dstskipleft / 3;
-#else
- int srcskipleft = s->gr[0x2f] & 0x07;
- int dstskipleft = srcskipleft * (DEPTH / 8);
-#endif
-
- if (s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_COLOREXPINV) {
- bits_xor = 0xff;
- col = s->cirrus_blt_bgcol;
- } else {
- bits_xor = 0x00;
- col = s->cirrus_blt_fgcol;
- }
- pattern_y = s->cirrus_blt_srcaddr & 7;
-
- for(y = 0; y < bltheight; y++) {
- bits = src[pattern_y] ^ bits_xor;
- bitpos = 7 - srcskipleft;
- d = dst + dstskipleft;
- for (x = dstskipleft; x < bltwidth; x += (DEPTH / 8)) {
- if ((bits >> bitpos) & 1) {
- PUTPIXEL();
- }
- d += (DEPTH / 8);
- bitpos = (bitpos - 1) & 7;
- }
- pattern_y = (pattern_y + 1) & 7;
- dst += dstpitch;
- }
-}
-
-static void
-glue(glue(glue(cirrus_colorexpand_pattern_, ROP_NAME), _),DEPTH)
- (CirrusVGAState * s, uint8_t * dst,
- const uint8_t * src,
- int dstpitch, int srcpitch,
- int bltwidth, int bltheight)
-{
- uint32_t colors[2];
- uint8_t *d;
- int x, y, bitpos, pattern_y;
- unsigned int bits;
- unsigned int col;
- int srcskipleft = s->gr[0x2f] & 0x07;
- int dstskipleft = srcskipleft * (DEPTH / 8);
-
- colors[0] = s->cirrus_blt_bgcol;
- colors[1] = s->cirrus_blt_fgcol;
- pattern_y = s->cirrus_blt_srcaddr & 7;
-
- for(y = 0; y < bltheight; y++) {
- bits = src[pattern_y];
- bitpos = 7 - srcskipleft;
- d = dst + dstskipleft;
- for (x = dstskipleft; x < bltwidth; x += (DEPTH / 8)) {
- col = colors[(bits >> bitpos) & 1];
- PUTPIXEL();
- d += (DEPTH / 8);
- bitpos = (bitpos - 1) & 7;
- }
- pattern_y = (pattern_y + 1) & 7;
- dst += dstpitch;
- }
-}
-
-static void
-glue(glue(glue(cirrus_fill_, ROP_NAME), _),DEPTH)
- (CirrusVGAState *s,
- uint8_t *dst, int dst_pitch,
- int width, int height)
-{
- uint8_t *d, *d1;
- uint32_t col;
- int x, y;
-
- col = s->cirrus_blt_fgcol;
-
- d1 = dst;
- for(y = 0; y < height; y++) {
- d = d1;
- for(x = 0; x < width; x += (DEPTH / 8)) {
- PUTPIXEL();
- d += (DEPTH / 8);
- }
- d1 += dst_pitch;
- }
-}
-
-#undef DEPTH
-#undef PUTPIXEL
+++ /dev/null
-/*
- * QEMU CUDA support
- *
- * Copyright (c) 2004 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "vl.h"
-
-//#define DEBUG_CUDA
-//#define DEBUG_CUDA_PACKET
-
-/* Bits in B data register: all active low */
-#define TREQ 0x08 /* Transfer request (input) */
-#define TACK 0x10 /* Transfer acknowledge (output) */
-#define TIP 0x20 /* Transfer in progress (output) */
-
-/* Bits in ACR */
-#define SR_CTRL 0x1c /* Shift register control bits */
-#define SR_EXT 0x0c /* Shift on external clock */
-#define SR_OUT 0x10 /* Shift out if 1 */
-
-/* Bits in IFR and IER */
-#define IER_SET 0x80 /* set bits in IER */
-#define IER_CLR 0 /* clear bits in IER */
-#define SR_INT 0x04 /* Shift register full/empty */
-#define T1_INT 0x40 /* Timer 1 interrupt */
-
-/* Bits in ACR */
-#define T1MODE 0xc0 /* Timer 1 mode */
-#define T1MODE_CONT 0x40 /* continuous interrupts */
-
-/* commands (1st byte) */
-#define ADB_PACKET 0
-#define CUDA_PACKET 1
-#define ERROR_PACKET 2
-#define TIMER_PACKET 3
-#define POWER_PACKET 4
-#define MACIIC_PACKET 5
-#define PMU_PACKET 6
-
-
-/* CUDA commands (2nd byte) */
-#define CUDA_WARM_START 0x0
-#define CUDA_AUTOPOLL 0x1
-#define CUDA_GET_6805_ADDR 0x2
-#define CUDA_GET_TIME 0x3
-#define CUDA_GET_PRAM 0x7
-#define CUDA_SET_6805_ADDR 0x8
-#define CUDA_SET_TIME 0x9
-#define CUDA_POWERDOWN 0xa
-#define CUDA_POWERUP_TIME 0xb
-#define CUDA_SET_PRAM 0xc
-#define CUDA_MS_RESET 0xd
-#define CUDA_SEND_DFAC 0xe
-#define CUDA_BATTERY_SWAP_SENSE 0x10
-#define CUDA_RESET_SYSTEM 0x11
-#define CUDA_SET_IPL 0x12
-#define CUDA_FILE_SERVER_FLAG 0x13
-#define CUDA_SET_AUTO_RATE 0x14
-#define CUDA_GET_AUTO_RATE 0x16
-#define CUDA_SET_DEVICE_LIST 0x19
-#define CUDA_GET_DEVICE_LIST 0x1a
-#define CUDA_SET_ONE_SECOND_MODE 0x1b
-#define CUDA_SET_POWER_MESSAGES 0x21
-#define CUDA_GET_SET_IIC 0x22
-#define CUDA_WAKEUP 0x23
-#define CUDA_TIMER_TICKLE 0x24
-#define CUDA_COMBINED_FORMAT_IIC 0x25
-
-#define CUDA_TIMER_FREQ (4700000 / 6)
-#define CUDA_ADB_POLL_FREQ 50
-
-typedef struct CUDATimer {
- unsigned int latch;
- uint16_t counter_value; /* counter value at load time */
- int64_t load_time;
- int64_t next_irq_time;
- QEMUTimer *timer;
-} CUDATimer;
-
-typedef struct CUDAState {
- /* cuda registers */
- uint8_t b; /* B-side data */
- uint8_t a; /* A-side data */
- uint8_t dirb; /* B-side direction (1=output) */
- uint8_t dira; /* A-side direction (1=output) */
- uint8_t sr; /* Shift register */
- uint8_t acr; /* Auxiliary control register */
- uint8_t pcr; /* Peripheral control register */
- uint8_t ifr; /* Interrupt flag register */
- uint8_t ier; /* Interrupt enable register */
- uint8_t anh; /* A-side data, no handshake */
-
- CUDATimer timers[2];
-
- uint8_t last_b; /* last value of B register */
- uint8_t last_acr; /* last value of B register */
-
- int data_in_size;
- int data_in_index;
- int data_out_index;
-
- int irq;
- openpic_t *openpic;
- uint8_t autopoll;
- uint8_t data_in[128];
- uint8_t data_out[16];
- QEMUTimer *adb_poll_timer;
-} CUDAState;
-
-static CUDAState cuda_state;
-ADBBusState adb_bus;
-
-static void cuda_update(CUDAState *s);
-static void cuda_receive_packet_from_host(CUDAState *s,
- const uint8_t *data, int len);
-static void cuda_timer_update(CUDAState *s, CUDATimer *ti,
- int64_t current_time);
-
-static void cuda_update_irq(CUDAState *s)
-{
- if (s->ifr & s->ier & (SR_INT | T1_INT)) {
- openpic_set_irq(s->openpic, s->irq, 1);
- } else {
- openpic_set_irq(s->openpic, s->irq, 0);
- }
-}
-
-static unsigned int get_counter(CUDATimer *s)
-{
- int64_t d;
- unsigned int counter;
-
- d = muldiv64(qemu_get_clock(vm_clock) - s->load_time,
- CUDA_TIMER_FREQ, ticks_per_sec);
- if (d <= s->counter_value) {
- counter = d;
- } else {
- counter = s->latch - 1 - ((d - s->counter_value) % s->latch);
- }
- return counter;
-}
-
-static void set_counter(CUDAState *s, CUDATimer *ti, unsigned int val)
-{
-#ifdef DEBUG_CUDA
- printf("cuda: T%d.counter=%d\n",
- 1 + (ti->timer == NULL), val);
-#endif
- ti->load_time = qemu_get_clock(vm_clock);
- ti->counter_value = val;
- cuda_timer_update(s, ti, ti->load_time);
-}
-
-static int64_t get_next_irq_time(CUDATimer *s, int64_t current_time)
-{
- int64_t d, next_time, base;
- /* current counter value */
- d = muldiv64(current_time - s->load_time,
- CUDA_TIMER_FREQ, ticks_per_sec);
- if (d <= s->counter_value) {
- next_time = s->counter_value + 1;
- } else {
- base = ((d - s->counter_value) / s->latch);
- base = (base * s->latch) + s->counter_value;
- next_time = base + s->latch;
- }
-#ifdef DEBUG_CUDA
- printf("latch=%d counter=%lld delta_next=%lld\n",
- s->latch, d, next_time - d);
-#endif
- next_time = muldiv64(next_time, ticks_per_sec, CUDA_TIMER_FREQ) +
- s->load_time;
- if (next_time <= current_time)
- next_time = current_time + 1;
- return next_time;
-}
-
-static void cuda_timer_update(CUDAState *s, CUDATimer *ti,
- int64_t current_time)
-{
- if (!ti->timer)
- return;
- if ((s->acr & T1MODE) != T1MODE_CONT) {
- qemu_del_timer(ti->timer);
- } else {
- ti->next_irq_time = get_next_irq_time(ti, current_time);
- qemu_mod_timer(ti->timer, ti->next_irq_time);
- }
-}
-
-static void cuda_timer1(void *opaque)
-{
- CUDAState *s = opaque;
- CUDATimer *ti = &s->timers[0];
-
- cuda_timer_update(s, ti, ti->next_irq_time);
- s->ifr |= T1_INT;
- cuda_update_irq(s);
-}
-
-static uint32_t cuda_readb(void *opaque, target_phys_addr_t addr)
-{
- CUDAState *s = opaque;
- uint32_t val;
-
- addr = (addr >> 9) & 0xf;
- switch(addr) {
- case 0:
- val = s->b;
- break;
- case 1:
- val = s->a;
- break;
- case 2:
- val = s->dirb;
- break;
- case 3:
- val = s->dira;
- break;
- case 4:
- val = get_counter(&s->timers[0]) & 0xff;
- s->ifr &= ~T1_INT;
- cuda_update_irq(s);
- break;
- case 5:
- val = get_counter(&s->timers[0]) >> 8;
- s->ifr &= ~T1_INT;
- cuda_update_irq(s);
- break;
- case 6:
- val = s->timers[0].latch & 0xff;
- break;
- case 7:
- val = (s->timers[0].latch >> 8) & 0xff;
- break;
- case 8:
- val = get_counter(&s->timers[1]) & 0xff;
- break;
- case 9:
- val = get_counter(&s->timers[1]) >> 8;
- break;
- case 10:
- val = s->sr;
- s->ifr &= ~SR_INT;
- cuda_update_irq(s);
- break;
- case 11:
- val = s->acr;
- break;
- case 12:
- val = s->pcr;
- break;
- case 13:
- val = s->ifr;
- break;
- case 14:
- val = s->ier;
- break;
- default:
- case 15:
- val = s->anh;
- break;
- }
-#ifdef DEBUG_CUDA
- if (addr != 13 || val != 0)
- printf("cuda: read: reg=0x%x val=%02x\n", addr, val);
-#endif
- return val;
-}
-
-static void cuda_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
- CUDAState *s = opaque;
-
- addr = (addr >> 9) & 0xf;
-#ifdef DEBUG_CUDA
- printf("cuda: write: reg=0x%x val=%02x\n", addr, val);
-#endif
-
- switch(addr) {
- case 0:
- s->b = val;
- cuda_update(s);
- break;
- case 1:
- s->a = val;
- break;
- case 2:
- s->dirb = val;
- break;
- case 3:
- s->dira = val;
- break;
- case 4:
- val = val | (get_counter(&s->timers[0]) & 0xff00);
- set_counter(s, &s->timers[0], val);
- break;
- case 5:
- val = (val << 8) | (get_counter(&s->timers[0]) & 0xff);
- set_counter(s, &s->timers[0], val);
- break;
- case 6:
- s->timers[0].latch = (s->timers[0].latch & 0xff00) | val;
- cuda_timer_update(s, &s->timers[0], qemu_get_clock(vm_clock));
- break;
- case 7:
- s->timers[0].latch = (s->timers[0].latch & 0xff) | (val << 8);
- cuda_timer_update(s, &s->timers[0], qemu_get_clock(vm_clock));
- break;
- case 8:
- val = val | (get_counter(&s->timers[1]) & 0xff00);
- set_counter(s, &s->timers[1], val);
- break;
- case 9:
- val = (val << 8) | (get_counter(&s->timers[1]) & 0xff);
- set_counter(s, &s->timers[1], val);
- break;
- case 10:
- s->sr = val;
- break;
- case 11:
- s->acr = val;
- cuda_timer_update(s, &s->timers[0], qemu_get_clock(vm_clock));
- cuda_update(s);
- break;
- case 12:
- s->pcr = val;
- break;
- case 13:
- /* reset bits */
- s->ifr &= ~val;
- cuda_update_irq(s);
- break;
- case 14:
- if (val & IER_SET) {
- /* set bits */
- s->ier |= val & 0x7f;
- } else {
- /* reset bits */
- s->ier &= ~val;
- }
- cuda_update_irq(s);
- break;
- default:
- case 15:
- s->anh = val;
- break;
- }
-}
-
-/* NOTE: TIP and TREQ are negated */
-static void cuda_update(CUDAState *s)
-{
- int packet_received, len;
-
- packet_received = 0;
- if (!(s->b & TIP)) {
- /* transfer requested from host */
-
- if (s->acr & SR_OUT) {
- /* data output */
- if ((s->b & (TACK | TIP)) != (s->last_b & (TACK | TIP))) {
- if (s->data_out_index < sizeof(s->data_out)) {
-#ifdef DEBUG_CUDA
- printf("cuda: send: %02x\n", s->sr);
-#endif
- s->data_out[s->data_out_index++] = s->sr;
- s->ifr |= SR_INT;
- cuda_update_irq(s);
- }
- }
- } else {
- if (s->data_in_index < s->data_in_size) {
- /* data input */
- if ((s->b & (TACK | TIP)) != (s->last_b & (TACK | TIP))) {
- s->sr = s->data_in[s->data_in_index++];
-#ifdef DEBUG_CUDA
- printf("cuda: recv: %02x\n", s->sr);
-#endif
- /* indicate end of transfer */
- if (s->data_in_index >= s->data_in_size) {
- s->b = (s->b | TREQ);
- }
- s->ifr |= SR_INT;
- cuda_update_irq(s);
- }
- }
- }
- } else {
- /* no transfer requested: handle sync case */
- if ((s->last_b & TIP) && (s->b & TACK) != (s->last_b & TACK)) {
- /* update TREQ state each time TACK change state */
- if (s->b & TACK)
- s->b = (s->b | TREQ);
- else
- s->b = (s->b & ~TREQ);
- s->ifr |= SR_INT;
- cuda_update_irq(s);
- } else {
- if (!(s->last_b & TIP)) {
- /* handle end of host to cuda transfert */
- packet_received = (s->data_out_index > 0);
- /* always an IRQ at the end of transfert */
- s->ifr |= SR_INT;
- cuda_update_irq(s);
- }
- /* signal if there is data to read */
- if (s->data_in_index < s->data_in_size) {
- s->b = (s->b & ~TREQ);
- }
- }
- }
-
- s->last_acr = s->acr;
- s->last_b = s->b;
-
- /* NOTE: cuda_receive_packet_from_host() can call cuda_update()
- recursively */
- if (packet_received) {
- len = s->data_out_index;
- s->data_out_index = 0;
- cuda_receive_packet_from_host(s, s->data_out, len);
- }
-}
-
-static void cuda_send_packet_to_host(CUDAState *s,
- const uint8_t *data, int len)
-{
-#ifdef DEBUG_CUDA_PACKET
- {
- int i;
- printf("cuda_send_packet_to_host:\n");
- for(i = 0; i < len; i++)
- printf(" %02x", data[i]);
- printf("\n");
- }
-#endif
- memcpy(s->data_in, data, len);
- s->data_in_size = len;
- s->data_in_index = 0;
- cuda_update(s);
- s->ifr |= SR_INT;
- cuda_update_irq(s);
-}
-
-static void cuda_adb_poll(void *opaque)
-{
- CUDAState *s = opaque;
- uint8_t obuf[ADB_MAX_OUT_LEN + 2];
- int olen;
-
- olen = adb_poll(&adb_bus, obuf + 2);
- if (olen > 0) {
- obuf[0] = ADB_PACKET;
- obuf[1] = 0x40; /* polled data */
- cuda_send_packet_to_host(s, obuf, olen + 2);
- }
- qemu_mod_timer(s->adb_poll_timer,
- qemu_get_clock(vm_clock) +
- (ticks_per_sec / CUDA_ADB_POLL_FREQ));
-}
-
-static void cuda_receive_packet(CUDAState *s,
- const uint8_t *data, int len)
-{
- uint8_t obuf[16];
- int ti, autopoll;
-
- switch(data[0]) {
- case CUDA_AUTOPOLL:
- autopoll = (data[1] != 0);
- if (autopoll != s->autopoll) {
- s->autopoll = autopoll;
- if (autopoll) {
- qemu_mod_timer(s->adb_poll_timer,
- qemu_get_clock(vm_clock) +
- (ticks_per_sec / CUDA_ADB_POLL_FREQ));
- } else {
- qemu_del_timer(s->adb_poll_timer);
- }
- }
- obuf[0] = CUDA_PACKET;
- obuf[1] = data[1];
- cuda_send_packet_to_host(s, obuf, 2);
- break;
- case CUDA_GET_TIME:
- /* XXX: add time support ? */
- ti = time(NULL);
- obuf[0] = CUDA_PACKET;
- obuf[1] = 0;
- obuf[2] = 0;
- obuf[3] = ti >> 24;
- obuf[4] = ti >> 16;
- obuf[5] = ti >> 8;
- obuf[6] = ti;
- cuda_send_packet_to_host(s, obuf, 7);
- break;
- case CUDA_SET_TIME:
- case CUDA_FILE_SERVER_FLAG:
- case CUDA_SET_DEVICE_LIST:
- case CUDA_SET_AUTO_RATE:
- case CUDA_SET_POWER_MESSAGES:
- obuf[0] = CUDA_PACKET;
- obuf[1] = 0;
- cuda_send_packet_to_host(s, obuf, 2);
- break;
- default:
- break;
- }
-}
-
-static void cuda_receive_packet_from_host(CUDAState *s,
- const uint8_t *data, int len)
-{
-#ifdef DEBUG_CUDA_PACKET
- {
- int i;
- printf("cuda_receive_packet_to_host:\n");
- for(i = 0; i < len; i++)
- printf(" %02x", data[i]);
- printf("\n");
- }
-#endif
- switch(data[0]) {
- case ADB_PACKET:
- {
- uint8_t obuf[ADB_MAX_OUT_LEN + 2];
- int olen;
- olen = adb_request(&adb_bus, obuf + 2, data + 1, len - 1);
- if (olen > 0) {
- obuf[0] = ADB_PACKET;
- obuf[1] = 0x00;
- } else {
- /* error */
- obuf[0] = ADB_PACKET;
- obuf[1] = -olen;
- olen = 0;
- }
- cuda_send_packet_to_host(s, obuf, olen + 2);
- }
- break;
- case CUDA_PACKET:
- cuda_receive_packet(s, data + 1, len - 1);
- break;
- }
-}
-
-static void cuda_writew (void *opaque, target_phys_addr_t addr, uint32_t value)
-{
-}
-
-static void cuda_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
-{
-}
-
-static uint32_t cuda_readw (void *opaque, target_phys_addr_t addr)
-{
- return 0;
-}
-
-static uint32_t cuda_readl (void *opaque, target_phys_addr_t addr)
-{
- return 0;
-}
-
-static CPUWriteMemoryFunc *cuda_write[] = {
- &cuda_writeb,
- &cuda_writew,
- &cuda_writel,
-};
-
-static CPUReadMemoryFunc *cuda_read[] = {
- &cuda_readb,
- &cuda_readw,
- &cuda_readl,
-};
-
-int cuda_init(openpic_t *openpic, int irq)
-{
- CUDAState *s = &cuda_state;
- int cuda_mem_index;
-
- s->openpic = openpic;
- s->irq = irq;
-
- s->timers[0].timer = qemu_new_timer(vm_clock, cuda_timer1, s);
- s->timers[0].latch = 0x10000;
- set_counter(s, &s->timers[0], 0xffff);
- s->timers[1].latch = 0x10000;
- s->ier = T1_INT | SR_INT;
- set_counter(s, &s->timers[1], 0xffff);
-
- s->adb_poll_timer = qemu_new_timer(vm_clock, cuda_adb_poll, s);
- cuda_mem_index = cpu_register_io_memory(0, cuda_read, cuda_write, s);
- return cuda_mem_index;
-}
+++ /dev/null
-/*
- * QEMU DMA emulation
- *
- * Copyright (c) 2003-2004 Vassili Karpov (malc)
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "vl.h"
-
-/* #define DEBUG_DMA */
-
-#define dolog(...) fprintf (stderr, "dma: " __VA_ARGS__)
-#ifdef DEBUG_DMA
-#define lwarn(...) fprintf (stderr, "dma: " __VA_ARGS__)
-#define linfo(...) fprintf (stderr, "dma: " __VA_ARGS__)
-#define ldebug(...) fprintf (stderr, "dma: " __VA_ARGS__)
-#else
-#define lwarn(...)
-#define linfo(...)
-#define ldebug(...)
-#endif
-
-#define LENOFA(a) ((int) (sizeof(a)/sizeof(a[0])))
-
-struct dma_regs {
- int now[2];
- uint16_t base[2];
- uint8_t mode;
- uint8_t page;
- uint8_t pageh;
- uint8_t dack;
- uint8_t eop;
- DMA_transfer_handler transfer_handler;
- void *opaque;
-};
-
-#define ADDR 0
-#define COUNT 1
-
-static struct dma_cont {
- uint8_t status;
- uint8_t command;
- uint8_t mask;
- uint8_t flip_flop;
- int dshift;
- struct dma_regs regs[4];
-} dma_controllers[2];
-
-enum {
- CMD_MEMORY_TO_MEMORY = 0x01,
- CMD_FIXED_ADDRESS = 0x02,
- CMD_BLOCK_CONTROLLER = 0x04,
- CMD_COMPRESSED_TIME = 0x08,
- CMD_CYCLIC_PRIORITY = 0x10,
- CMD_EXTENDED_WRITE = 0x20,
- CMD_LOW_DREQ = 0x40,
- CMD_LOW_DACK = 0x80,
- CMD_NOT_SUPPORTED = CMD_MEMORY_TO_MEMORY | CMD_FIXED_ADDRESS
- | CMD_COMPRESSED_TIME | CMD_CYCLIC_PRIORITY | CMD_EXTENDED_WRITE
- | CMD_LOW_DREQ | CMD_LOW_DACK
-
-};
-
-static int channels[8] = {-1, 2, 3, 1, -1, -1, -1, 0};
-
-static void write_page (void *opaque, uint32_t nport, uint32_t data)
-{
- struct dma_cont *d = opaque;
- int ichan;
-
- ichan = channels[nport & 7];
- if (-1 == ichan) {
- dolog ("invalid channel %#x %#x\n", nport, data);
- return;
- }
- d->regs[ichan].page = data;
-}
-
-static void write_pageh (void *opaque, uint32_t nport, uint32_t data)
-{
- struct dma_cont *d = opaque;
- int ichan;
-
- ichan = channels[nport & 7];
- if (-1 == ichan) {
- dolog ("invalid channel %#x %#x\n", nport, data);
- return;
- }
- d->regs[ichan].pageh = data;
-}
-
-static uint32_t read_page (void *opaque, uint32_t nport)
-{
- struct dma_cont *d = opaque;
- int ichan;
-
- ichan = channels[nport & 7];
- if (-1 == ichan) {
- dolog ("invalid channel read %#x\n", nport);
- return 0;
- }
- return d->regs[ichan].page;
-}
-
-static uint32_t read_pageh (void *opaque, uint32_t nport)
-{
- struct dma_cont *d = opaque;
- int ichan;
-
- ichan = channels[nport & 7];
- if (-1 == ichan) {
- dolog ("invalid channel read %#x\n", nport);
- return 0;
- }
- return d->regs[ichan].pageh;
-}
-
-static inline void init_chan (struct dma_cont *d, int ichan)
-{
- struct dma_regs *r;
-
- r = d->regs + ichan;
- r->now[ADDR] = r->base[ADDR] << d->dshift;
- r->now[COUNT] = 0;
-}
-
-static inline int getff (struct dma_cont *d)
-{
- int ff;
-
- ff = d->flip_flop;
- d->flip_flop = !ff;
- return ff;
-}
-
-static uint32_t read_chan (void *opaque, uint32_t nport)
-{
- struct dma_cont *d = opaque;
- int ichan, nreg, iport, ff, val, dir;
- struct dma_regs *r;
-
- iport = (nport >> d->dshift) & 0x0f;
- ichan = iport >> 1;
- nreg = iport & 1;
- r = d->regs + ichan;
-
- dir = ((r->mode >> 5) & 1) ? -1 : 1;
- ff = getff (d);
- if (nreg)
- val = (r->base[COUNT] << d->dshift) - r->now[COUNT];
- else
- val = r->now[ADDR] + r->now[COUNT] * dir;
-
- ldebug ("read_chan %#x -> %d\n", iport, val);
- return (val >> (d->dshift + (ff << 3))) & 0xff;
-}
-
-static void write_chan (void *opaque, uint32_t nport, uint32_t data)
-{
- struct dma_cont *d = opaque;
- int iport, ichan, nreg;
- struct dma_regs *r;
-
- iport = (nport >> d->dshift) & 0x0f;
- ichan = iport >> 1;
- nreg = iport & 1;
- r = d->regs + ichan;
- if (getff (d)) {
- r->base[nreg] = (r->base[nreg] & 0xff) | ((data << 8) & 0xff00);
- init_chan (d, ichan);
- } else {
- r->base[nreg] = (r->base[nreg] & 0xff00) | (data & 0xff);
- }
-}
-
-static void write_cont (void *opaque, uint32_t nport, uint32_t data)
-{
- struct dma_cont *d = opaque;
- int iport, ichan = 0;
-
- iport = (nport >> d->dshift) & 0x0f;
- switch (iport) {
- case 0x08: /* command */
- if ((data != 0) && (data & CMD_NOT_SUPPORTED)) {
- dolog ("command %#x not supported\n", data);
- return;
- }
- d->command = data;
- break;
-
- case 0x09:
- ichan = data & 3;
- if (data & 4) {
- d->status |= 1 << (ichan + 4);
- }
- else {
- d->status &= ~(1 << (ichan + 4));
- }
- d->status &= ~(1 << ichan);
- break;
-
- case 0x0a: /* single mask */
- if (data & 4)
- d->mask |= 1 << (data & 3);
- else
- d->mask &= ~(1 << (data & 3));
- break;
-
- case 0x0b: /* mode */
- {
- ichan = data & 3;
-#ifdef DEBUG_DMA
- {
- int op, ai, dir, opmode;
- op = (data >> 2) & 3;
- ai = (data >> 4) & 1;
- dir = (data >> 5) & 1;
- opmode = (data >> 6) & 3;
-
- linfo ("ichan %d, op %d, ai %d, dir %d, opmode %d\n",
- ichan, op, ai, dir, opmode);
- }
-#endif
- d->regs[ichan].mode = data;
- break;
- }
-
- case 0x0c: /* clear flip flop */
- d->flip_flop = 0;
- break;
-
- case 0x0d: /* reset */
- d->flip_flop = 0;
- d->mask = ~0;
- d->status = 0;
- d->command = 0;
- break;
-
- case 0x0e: /* clear mask for all channels */
- d->mask = 0;
- break;
-
- case 0x0f: /* write mask for all channels */
- d->mask = data;
- break;
-
- default:
- dolog ("unknown iport %#x\n", iport);
- break;
- }
-
-#ifdef DEBUG_DMA
- if (0xc != iport) {
- linfo ("write_cont: nport %#06x, ichan % 2d, val %#06x\n",
- nport, ichan, data);
- }
-#endif
-}
-
-static uint32_t read_cont (void *opaque, uint32_t nport)
-{
- struct dma_cont *d = opaque;
- int iport, val;
-
- iport = (nport >> d->dshift) & 0x0f;
- switch (iport) {
- case 0x08: /* status */
- val = d->status;
- d->status &= 0xf0;
- break;
- case 0x0f: /* mask */
- val = d->mask;
- break;
- default:
- val = 0;
- break;
- }
-
- ldebug ("read_cont: nport %#06x, iport %#04x val %#x\n", nport, iport, val);
- return val;
-}
-
-int DMA_get_channel_mode (int nchan)
-{
- return dma_controllers[nchan > 3].regs[nchan & 3].mode;
-}
-
-void DMA_hold_DREQ (int nchan)
-{
- int ncont, ichan;
-
- ncont = nchan > 3;
- ichan = nchan & 3;
- linfo ("held cont=%d chan=%d\n", ncont, ichan);
- dma_controllers[ncont].status |= 1 << (ichan + 4);
-}
-
-void DMA_release_DREQ (int nchan)
-{
- int ncont, ichan;
-
- ncont = nchan > 3;
- ichan = nchan & 3;
- linfo ("released cont=%d chan=%d\n", ncont, ichan);
- dma_controllers[ncont].status &= ~(1 << (ichan + 4));
-}
-
-static void channel_run (int ncont, int ichan)
-{
- int n;
- struct dma_regs *r = &dma_controllers[ncont].regs[ichan];
-#ifdef DEBUG_DMA
- int dir, opmode;
-
- dir = (r->mode >> 5) & 1;
- opmode = (r->mode >> 6) & 3;
-
- if (dir) {
- dolog ("DMA in address decrement mode\n");
- }
- if (opmode != 1) {
- dolog ("DMA not in single mode select %#x\n", opmode);
- }
-#endif
-
- r = dma_controllers[ncont].regs + ichan;
- n = r->transfer_handler (r->opaque, ichan + (ncont << 2),
- r->now[COUNT], (r->base[COUNT] + 1) << ncont);
- r->now[COUNT] = n;
- ldebug ("dma_pos %d size %d\n", n, (r->base[COUNT] + 1) << ncont);
-}
-
-void DMA_run (void)
-{
- struct dma_cont *d;
- int icont, ichan;
-
- d = dma_controllers;
-
- for (icont = 0; icont < 2; icont++, d++) {
- for (ichan = 0; ichan < 4; ichan++) {
- int mask;
-
- mask = 1 << ichan;
-
- if ((0 == (d->mask & mask)) && (0 != (d->status & (mask << 4))))
- channel_run (icont, ichan);
- }
- }
-}
-
-void DMA_register_channel (int nchan,
- DMA_transfer_handler transfer_handler,
- void *opaque)
-{
- struct dma_regs *r;
- int ichan, ncont;
-
- ncont = nchan > 3;
- ichan = nchan & 3;
-
- r = dma_controllers[ncont].regs + ichan;
- r->transfer_handler = transfer_handler;
- r->opaque = opaque;
-}
-
-int DMA_read_memory (int nchan, void *buf, int pos, int len)
-{
- struct dma_regs *r = &dma_controllers[nchan > 3].regs[nchan & 3];
- target_ulong addr = ((r->pageh & 0x7f) << 24) | (r->page << 16) | r->now[ADDR];
-
- if (r->mode & 0x20) {
- int i;
- uint8_t *p = buf;
-
- cpu_physical_memory_read (addr - pos - len, buf, len);
- /* What about 16bit transfers? */
- for (i = 0; i < len >> 1; i++) {
- uint8_t b = p[len - i - 1];
- p[i] = b;
- }
- }
- else
- cpu_physical_memory_read (addr + pos, buf, len);
-
- return len;
-}
-
-int DMA_write_memory (int nchan, void *buf, int pos, int len)
-{
- struct dma_regs *r = &dma_controllers[nchan > 3].regs[nchan & 3];
- target_ulong addr = ((r->pageh & 0x7f) << 24) | (r->page << 16) | r->now[ADDR];
-
- if (r->mode & 0x20) {
- int i;
- uint8_t *p = buf;
-
- cpu_physical_memory_write (addr - pos - len, buf, len);
- /* What about 16bit transfers? */
- for (i = 0; i < len; i++) {
- uint8_t b = p[len - i - 1];
- p[i] = b;
- }
- }
- else
- cpu_physical_memory_write (addr + pos, buf, len);
-
- return len;
-}
-
-/* request the emulator to transfer a new DMA memory block ASAP */
-void DMA_schedule(int nchan)
-{
- cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT);
-}
-
-static void dma_reset(void *opaque)
-{
- struct dma_cont *d = opaque;
- write_cont (d, (0x0d << d->dshift), 0);
-}
-
-/* dshift = 0: 8 bit DMA, 1 = 16 bit DMA */
-static void dma_init2(struct dma_cont *d, int base, int dshift,
- int page_base, int pageh_base)
-{
- const static int page_port_list[] = { 0x1, 0x2, 0x3, 0x7 };
- int i;
-
- d->dshift = dshift;
- for (i = 0; i < 8; i++) {
- register_ioport_write (base + (i << dshift), 1, 1, write_chan, d);
- register_ioport_read (base + (i << dshift), 1, 1, read_chan, d);
- }
- for (i = 0; i < LENOFA (page_port_list); i++) {
- register_ioport_write (page_base + page_port_list[i], 1, 1,
- write_page, d);
- register_ioport_read (page_base + page_port_list[i], 1, 1,
- read_page, d);
- if (pageh_base >= 0) {
- register_ioport_write (pageh_base + page_port_list[i], 1, 1,
- write_pageh, d);
- register_ioport_read (pageh_base + page_port_list[i], 1, 1,
- read_pageh, d);
- }
- }
- for (i = 0; i < 8; i++) {
- register_ioport_write (base + ((i + 8) << dshift), 1, 1,
- write_cont, d);
- register_ioport_read (base + ((i + 8) << dshift), 1, 1,
- read_cont, d);
- }
- qemu_register_reset(dma_reset, d);
- dma_reset(d);
-}
-
-static void dma_save (QEMUFile *f, void *opaque)
-{
- struct dma_cont *d = opaque;
- int i;
-
- /* qemu_put_8s (f, &d->status); */
- qemu_put_8s (f, &d->command);
- qemu_put_8s (f, &d->mask);
- qemu_put_8s (f, &d->flip_flop);
- qemu_put_be32s (f, &d->dshift);
-
- for (i = 0; i < 4; ++i) {
- struct dma_regs *r = &d->regs[i];
- qemu_put_be32s (f, &r->now[0]);
- qemu_put_be32s (f, &r->now[1]);
- qemu_put_be16s (f, &r->base[0]);
- qemu_put_be16s (f, &r->base[1]);
- qemu_put_8s (f, &r->mode);
- qemu_put_8s (f, &r->page);
- qemu_put_8s (f, &r->pageh);
- qemu_put_8s (f, &r->dack);
- qemu_put_8s (f, &r->eop);
- }
-}
-
-static int dma_load (QEMUFile *f, void *opaque, int version_id)
-{
- struct dma_cont *d = opaque;
- int i;
-
- if (version_id != 1)
- return -EINVAL;
-
- /* qemu_get_8s (f, &d->status); */
- qemu_get_8s (f, &d->command);
- qemu_get_8s (f, &d->mask);
- qemu_get_8s (f, &d->flip_flop);
- qemu_get_be32s (f, &d->dshift);
-
- for (i = 0; i < 4; ++i) {
- struct dma_regs *r = &d->regs[i];
- qemu_get_be32s (f, &r->now[0]);
- qemu_get_be32s (f, &r->now[1]);
- qemu_get_be16s (f, &r->base[0]);
- qemu_get_be16s (f, &r->base[1]);
- qemu_get_8s (f, &r->mode);
- qemu_get_8s (f, &r->page);
- qemu_get_8s (f, &r->pageh);
- qemu_get_8s (f, &r->dack);
- qemu_get_8s (f, &r->eop);
- }
- return 0;
-}
-
-void DMA_init (int high_page_enable)
-{
- dma_init2(&dma_controllers[0], 0x00, 0, 0x80,
- high_page_enable ? 0x480 : -1);
- dma_init2(&dma_controllers[1], 0xc0, 1, 0x88,
- high_page_enable ? 0x488 : -1);
- register_savevm ("dma", 0, 1, dma_save, dma_load, &dma_controllers[0]);
- register_savevm ("dma", 1, 1, dma_save, dma_load, &dma_controllers[1]);
-}
+++ /dev/null
-/*
- * QEMU Floppy disk emulator (Intel 82078)
- *
- * Copyright (c) 2003 Jocelyn Mayer
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "vl.h"
-
-/********************************************************/
-/* debug Floppy devices */
-//#define DEBUG_FLOPPY
-
-#ifdef DEBUG_FLOPPY
-#define FLOPPY_DPRINTF(fmt, args...) \
-do { printf("FLOPPY: " fmt , ##args); } while (0)
-#else
-#define FLOPPY_DPRINTF(fmt, args...)
-#endif
-
-#define FLOPPY_ERROR(fmt, args...) \
-do { printf("FLOPPY ERROR: %s: " fmt, __func__ , ##args); } while (0)
-
-/********************************************************/
-/* Floppy drive emulation */
-
-/* Will always be a fixed parameter for us */
-#define FD_SECTOR_LEN 512
-#define FD_SECTOR_SC 2 /* Sector size code */
-
-/* Floppy disk drive emulation */
-typedef enum fdisk_type_t {
- FDRIVE_DISK_288 = 0x01, /* 2.88 MB disk */
- FDRIVE_DISK_144 = 0x02, /* 1.44 MB disk */
- FDRIVE_DISK_720 = 0x03, /* 720 kB disk */
- FDRIVE_DISK_USER = 0x04, /* User defined geometry */
- FDRIVE_DISK_NONE = 0x05, /* No disk */
-} fdisk_type_t;
-
-typedef enum fdrive_type_t {
- FDRIVE_DRV_144 = 0x00, /* 1.44 MB 3"5 drive */
- FDRIVE_DRV_288 = 0x01, /* 2.88 MB 3"5 drive */
- FDRIVE_DRV_120 = 0x02, /* 1.2 MB 5"25 drive */
- FDRIVE_DRV_NONE = 0x03, /* No drive connected */
-} fdrive_type_t;
-
-typedef enum fdrive_flags_t {
- FDRIVE_MOTOR_ON = 0x01, /* motor on/off */
- FDRIVE_REVALIDATE = 0x02, /* Revalidated */
-} fdrive_flags_t;
-
-typedef enum fdisk_flags_t {
- FDISK_DBL_SIDES = 0x01,
-} fdisk_flags_t;
-
-typedef struct fdrive_t {
- BlockDriverState *bs;
- /* Drive status */
- fdrive_type_t drive;
- fdrive_flags_t drflags;
- uint8_t perpendicular; /* 2.88 MB access mode */
- /* Position */
- uint8_t head;
- uint8_t track;
- uint8_t sect;
- /* Last operation status */
- uint8_t dir; /* Direction */
- uint8_t rw; /* Read/write */
- /* Media */
- fdisk_flags_t flags;
- uint8_t last_sect; /* Nb sector per track */
- uint8_t max_track; /* Nb of tracks */
- uint16_t bps; /* Bytes per sector */
- uint8_t ro; /* Is read-only */
-} fdrive_t;
-
-static void fd_init (fdrive_t *drv, BlockDriverState *bs)
-{
- /* Drive */
- drv->bs = bs;
- drv->drive = FDRIVE_DRV_NONE;
- drv->drflags = 0;
- drv->perpendicular = 0;
- /* Disk */
- drv->last_sect = 0;
- drv->max_track = 0;
-}
-
-static int _fd_sector (uint8_t head, uint8_t track,
- uint8_t sect, uint8_t last_sect)
-{
- return (((track * 2) + head) * last_sect) + sect - 1;
-}
-
-/* Returns current position, in sectors, for given drive */
-static int fd_sector (fdrive_t *drv)
-{
- return _fd_sector(drv->head, drv->track, drv->sect, drv->last_sect);
-}
-
-static int fd_seek (fdrive_t *drv, uint8_t head, uint8_t track, uint8_t sect,
- int enable_seek)
-{
- uint32_t sector;
- int ret;
-
- if (track > drv->max_track ||
- (head != 0 && (drv->flags & FDISK_DBL_SIDES) == 0)) {
- FLOPPY_DPRINTF("try to read %d %02x %02x (max=%d %d %02x %02x)\n",
- head, track, sect, 1,
- (drv->flags & FDISK_DBL_SIDES) == 0 ? 0 : 1,
- drv->max_track, drv->last_sect);
- return 2;
- }
- if (sect > drv->last_sect) {
- FLOPPY_DPRINTF("try to read %d %02x %02x (max=%d %d %02x %02x)\n",
- head, track, sect, 1,
- (drv->flags & FDISK_DBL_SIDES) == 0 ? 0 : 1,
- drv->max_track, drv->last_sect);
- return 3;
- }
- sector = _fd_sector(head, track, sect, drv->last_sect);
- ret = 0;
- if (sector != fd_sector(drv)) {
-#if 0
- if (!enable_seek) {
- FLOPPY_ERROR("no implicit seek %d %02x %02x (max=%d %02x %02x)\n",
- head, track, sect, 1, drv->max_track, drv->last_sect);
- return 4;
- }
-#endif
- drv->head = head;
- if (drv->track != track)
- ret = 1;
- drv->track = track;
- drv->sect = sect;
- }
-
- return ret;
-}
-
-/* Set drive back to track 0 */
-static void fd_recalibrate (fdrive_t *drv)
-{
- FLOPPY_DPRINTF("recalibrate\n");
- drv->head = 0;
- drv->track = 0;
- drv->sect = 1;
- drv->dir = 1;
- drv->rw = 0;
-}
-
-/* Recognize floppy formats */
-typedef struct fd_format_t {
- fdrive_type_t drive;
- fdisk_type_t disk;
- uint8_t last_sect;
- uint8_t max_track;
- uint8_t max_head;
- const unsigned char *str;
-} fd_format_t;
-
-static fd_format_t fd_formats[] = {
- /* First entry is default format */
- /* 1.44 MB 3"1/2 floppy disks */
- { FDRIVE_DRV_144, FDRIVE_DISK_144, 18, 80, 1, "1.44 MB 3\"1/2", },
- { FDRIVE_DRV_144, FDRIVE_DISK_144, 20, 80, 1, "1.6 MB 3\"1/2", },
- { FDRIVE_DRV_144, FDRIVE_DISK_144, 21, 80, 1, "1.68 MB 3\"1/2", },
- { FDRIVE_DRV_144, FDRIVE_DISK_144, 21, 82, 1, "1.72 MB 3\"1/2", },
- { FDRIVE_DRV_144, FDRIVE_DISK_144, 21, 83, 1, "1.74 MB 3\"1/2", },
- { FDRIVE_DRV_144, FDRIVE_DISK_144, 22, 80, 1, "1.76 MB 3\"1/2", },
- { FDRIVE_DRV_144, FDRIVE_DISK_144, 23, 80, 1, "1.84 MB 3\"1/2", },
- { FDRIVE_DRV_144, FDRIVE_DISK_144, 24, 80, 1, "1.92 MB 3\"1/2", },
- /* 2.88 MB 3"1/2 floppy disks */
- { FDRIVE_DRV_288, FDRIVE_DISK_288, 36, 80, 1, "2.88 MB 3\"1/2", },
- { FDRIVE_DRV_288, FDRIVE_DISK_288, 39, 80, 1, "3.12 MB 3\"1/2", },
- { FDRIVE_DRV_288, FDRIVE_DISK_288, 40, 80, 1, "3.2 MB 3\"1/2", },
- { FDRIVE_DRV_288, FDRIVE_DISK_288, 44, 80, 1, "3.52 MB 3\"1/2", },
- { FDRIVE_DRV_288, FDRIVE_DISK_288, 48, 80, 1, "3.84 MB 3\"1/2", },
- /* 720 kB 3"1/2 floppy disks */
- { FDRIVE_DRV_144, FDRIVE_DISK_720, 9, 80, 1, "720 kB 3\"1/2", },
- { FDRIVE_DRV_144, FDRIVE_DISK_720, 10, 80, 1, "800 kB 3\"1/2", },
- { FDRIVE_DRV_144, FDRIVE_DISK_720, 10, 82, 1, "820 kB 3\"1/2", },
- { FDRIVE_DRV_144, FDRIVE_DISK_720, 10, 83, 1, "830 kB 3\"1/2", },
- { FDRIVE_DRV_144, FDRIVE_DISK_720, 13, 80, 1, "1.04 MB 3\"1/2", },
- { FDRIVE_DRV_144, FDRIVE_DISK_720, 14, 80, 1, "1.12 MB 3\"1/2", },
- /* 1.2 MB 5"1/4 floppy disks */
- { FDRIVE_DRV_120, FDRIVE_DISK_288, 15, 80, 1, "1.2 kB 5\"1/4", },
- { FDRIVE_DRV_120, FDRIVE_DISK_288, 18, 80, 1, "1.44 MB 5\"1/4", },
- { FDRIVE_DRV_120, FDRIVE_DISK_288, 18, 82, 1, "1.48 MB 5\"1/4", },
- { FDRIVE_DRV_120, FDRIVE_DISK_288, 18, 83, 1, "1.49 MB 5\"1/4", },
- { FDRIVE_DRV_120, FDRIVE_DISK_288, 20, 80, 1, "1.6 MB 5\"1/4", },
- /* 720 kB 5"1/4 floppy disks */
- { FDRIVE_DRV_120, FDRIVE_DISK_288, 9, 80, 1, "720 kB 5\"1/4", },
- { FDRIVE_DRV_120, FDRIVE_DISK_288, 11, 80, 1, "880 kB 5\"1/4", },
- /* 360 kB 5"1/4 floppy disks */
- { FDRIVE_DRV_120, FDRIVE_DISK_288, 9, 40, 1, "360 kB 5\"1/4", },
- { FDRIVE_DRV_120, FDRIVE_DISK_288, 9, 40, 0, "180 kB 5\"1/4", },
- { FDRIVE_DRV_120, FDRIVE_DISK_288, 10, 41, 1, "410 kB 5\"1/4", },
- { FDRIVE_DRV_120, FDRIVE_DISK_288, 10, 42, 1, "420 kB 5\"1/4", },
- /* 320 kB 5"1/4 floppy disks */
- { FDRIVE_DRV_120, FDRIVE_DISK_288, 8, 40, 1, "320 kB 5\"1/4", },
- { FDRIVE_DRV_120, FDRIVE_DISK_288, 8, 40, 0, "160 kB 5\"1/4", },
- /* 360 kB must match 5"1/4 better than 3"1/2... */
- { FDRIVE_DRV_144, FDRIVE_DISK_720, 9, 80, 0, "360 kB 3\"1/2", },
- /* end */
- { FDRIVE_DRV_NONE, FDRIVE_DISK_NONE, -1, -1, 0, NULL, },
-};
-
-/* Revalidate a disk drive after a disk change */
-static void fd_revalidate (fdrive_t *drv)
-{
- fd_format_t *parse;
- int64_t nb_sectors, size;
- int i, first_match, match;
- int nb_heads, max_track, last_sect, ro;
-
- FLOPPY_DPRINTF("revalidate\n");
- drv->drflags &= ~FDRIVE_REVALIDATE;
- if (drv->bs != NULL && bdrv_is_inserted(drv->bs)) {
- ro = bdrv_is_read_only(drv->bs);
- bdrv_get_geometry_hint(drv->bs, &nb_heads, &max_track, &last_sect);
- if (nb_heads != 0 && max_track != 0 && last_sect != 0) {
- FLOPPY_DPRINTF("User defined disk (%d %d %d)",
- nb_heads - 1, max_track, last_sect);
- } else {
- bdrv_get_geometry(drv->bs, &nb_sectors);
- match = -1;
- first_match = -1;
- for (i = 0;; i++) {
- parse = &fd_formats[i];
- if (parse->drive == FDRIVE_DRV_NONE)
- break;
- if (drv->drive == parse->drive ||
- drv->drive == FDRIVE_DRV_NONE) {
- size = (parse->max_head + 1) * parse->max_track *
- parse->last_sect;
- if (nb_sectors == size) {
- match = i;
- break;
- }
- if (first_match == -1)
- first_match = i;
- }
- }
- if (match == -1) {
- if (first_match == -1)
- match = 1;
- else
- match = first_match;
- parse = &fd_formats[match];
- }
- nb_heads = parse->max_head + 1;
- max_track = parse->max_track;
- last_sect = parse->last_sect;
- drv->drive = parse->drive;
- FLOPPY_DPRINTF("%s floppy disk (%d h %d t %d s) %s\n", parse->str,
- nb_heads, max_track, last_sect, ro ? "ro" : "rw");
- }
- if (nb_heads == 1) {
- drv->flags &= ~FDISK_DBL_SIDES;
- } else {
- drv->flags |= FDISK_DBL_SIDES;
- }
- drv->max_track = max_track;
- drv->last_sect = last_sect;
- drv->ro = ro;
- } else {
- FLOPPY_DPRINTF("No disk in drive\n");
- drv->last_sect = 0;
- drv->max_track = 0;
- drv->flags &= ~FDISK_DBL_SIDES;
- }
- drv->drflags |= FDRIVE_REVALIDATE;
-}
-
-/* Motor control */
-static void fd_start (fdrive_t *drv)
-{
- drv->drflags |= FDRIVE_MOTOR_ON;
-}
-
-static void fd_stop (fdrive_t *drv)
-{
- drv->drflags &= ~FDRIVE_MOTOR_ON;
-}
-
-/* Re-initialise a drives (motor off, repositioned) */
-static void fd_reset (fdrive_t *drv)
-{
- fd_stop(drv);
- fd_recalibrate(drv);
-}
-
-/********************************************************/
-/* Intel 82078 floppy disk controller emulation */
-
-static void fdctrl_reset (fdctrl_t *fdctrl, int do_irq);
-static void fdctrl_reset_fifo (fdctrl_t *fdctrl);
-static int fdctrl_transfer_handler (void *opaque, int nchan,
- int dma_pos, int dma_len);
-static void fdctrl_raise_irq (fdctrl_t *fdctrl, uint8_t status);
-static void fdctrl_result_timer(void *opaque);
-
-static uint32_t fdctrl_read_statusB (fdctrl_t *fdctrl);
-static uint32_t fdctrl_read_dor (fdctrl_t *fdctrl);
-static void fdctrl_write_dor (fdctrl_t *fdctrl, uint32_t value);
-static uint32_t fdctrl_read_tape (fdctrl_t *fdctrl);
-static void fdctrl_write_tape (fdctrl_t *fdctrl, uint32_t value);
-static uint32_t fdctrl_read_main_status (fdctrl_t *fdctrl);
-static void fdctrl_write_rate (fdctrl_t *fdctrl, uint32_t value);
-static uint32_t fdctrl_read_data (fdctrl_t *fdctrl);
-static void fdctrl_write_data (fdctrl_t *fdctrl, uint32_t value);
-static uint32_t fdctrl_read_dir (fdctrl_t *fdctrl);
-
-enum {
- FD_CTRL_ACTIVE = 0x01, /* XXX: suppress that */
- FD_CTRL_RESET = 0x02,
- FD_CTRL_SLEEP = 0x04, /* XXX: suppress that */
- FD_CTRL_BUSY = 0x08, /* dma transfer in progress */
- FD_CTRL_INTR = 0x10,
-};
-
-enum {
- FD_DIR_WRITE = 0,
- FD_DIR_READ = 1,
- FD_DIR_SCANE = 2,
- FD_DIR_SCANL = 3,
- FD_DIR_SCANH = 4,
-};
-
-enum {
- FD_STATE_CMD = 0x00,
- FD_STATE_STATUS = 0x01,
- FD_STATE_DATA = 0x02,
- FD_STATE_STATE = 0x03,
- FD_STATE_MULTI = 0x10,
- FD_STATE_SEEK = 0x20,
- FD_STATE_FORMAT = 0x40,
-};
-
-#define FD_STATE(state) ((state) & FD_STATE_STATE)
-#define FD_SET_STATE(state, new_state) \
-do { (state) = ((state) & ~FD_STATE_STATE) | (new_state); } while (0)
-#define FD_MULTI_TRACK(state) ((state) & FD_STATE_MULTI)
-#define FD_DID_SEEK(state) ((state) & FD_STATE_SEEK)
-#define FD_FORMAT_CMD(state) ((state) & FD_STATE_FORMAT)
-
-struct fdctrl_t {
- fdctrl_t *fdctrl;
- /* Controller's identification */
- uint8_t version;
- /* HW */
- int irq_lvl;
- int dma_chann;
- uint32_t io_base;
- /* Controller state */
- QEMUTimer *result_timer;
- uint8_t state;
- uint8_t dma_en;
- uint8_t cur_drv;
- uint8_t bootsel;
- /* Command FIFO */
- uint8_t fifo[FD_SECTOR_LEN];
- uint32_t data_pos;
- uint32_t data_len;
- uint8_t data_state;
- uint8_t data_dir;
- uint8_t int_status;
- uint8_t eot; /* last wanted sector */
- /* States kept only to be returned back */
- /* Timers state */
- uint8_t timer0;
- uint8_t timer1;
- /* precompensation */
- uint8_t precomp_trk;
- uint8_t config;
- uint8_t lock;
- /* Power down config (also with status regB access mode */
- uint8_t pwrd;
- /* Floppy drives */
- fdrive_t drives[2];
-};
-
-static uint32_t fdctrl_read (void *opaque, uint32_t reg)
-{
- fdctrl_t *fdctrl = opaque;
- uint32_t retval;
-
- switch (reg & 0x07) {
- case 0x01:
- retval = fdctrl_read_statusB(fdctrl);
- break;
- case 0x02:
- retval = fdctrl_read_dor(fdctrl);
- break;
- case 0x03:
- retval = fdctrl_read_tape(fdctrl);
- break;
- case 0x04:
- retval = fdctrl_read_main_status(fdctrl);
- break;
- case 0x05:
- retval = fdctrl_read_data(fdctrl);
- break;
- case 0x07:
- retval = fdctrl_read_dir(fdctrl);
- break;
- default:
- retval = (uint32_t)(-1);
- break;
- }
- FLOPPY_DPRINTF("read reg%d: 0x%02x\n", reg & 7, retval);
-
- return retval;
-}
-
-static void fdctrl_write (void *opaque, uint32_t reg, uint32_t value)
-{
- fdctrl_t *fdctrl = opaque;
-
- FLOPPY_DPRINTF("write reg%d: 0x%02x\n", reg & 7, value);
-
- switch (reg & 0x07) {
- case 0x02:
- fdctrl_write_dor(fdctrl, value);
- break;
- case 0x03:
- fdctrl_write_tape(fdctrl, value);
- break;
- case 0x04:
- fdctrl_write_rate(fdctrl, value);
- break;
- case 0x05:
- fdctrl_write_data(fdctrl, value);
- break;
- default:
- break;
- }
-}
-
-static void fd_change_cb (void *opaque)
-{
- fdrive_t *drv = opaque;
-
- FLOPPY_DPRINTF("disk change\n");
- fd_revalidate(drv);
-#if 0
- fd_recalibrate(drv);
- fdctrl_reset_fifo(drv->fdctrl);
- fdctrl_raise_irq(drv->fdctrl, 0x20);
-#endif
-}
-
-fdctrl_t *fdctrl_init (int irq_lvl, int dma_chann, int mem_mapped,
- uint32_t io_base,
- BlockDriverState **fds)
-{
- fdctrl_t *fdctrl;
-// int io_mem;
- int i;
-
- FLOPPY_DPRINTF("init controller\n");
- fdctrl = qemu_mallocz(sizeof(fdctrl_t));
- if (!fdctrl)
- return NULL;
- fdctrl->result_timer = qemu_new_timer(vm_clock,
- fdctrl_result_timer, fdctrl);
-
- fdctrl->version = 0x90; /* Intel 82078 controller */
- fdctrl->irq_lvl = irq_lvl;
- fdctrl->dma_chann = dma_chann;
- fdctrl->io_base = io_base;
- fdctrl->config = 0x60; /* Implicit seek, polling & FIFO enabled */
- if (fdctrl->dma_chann != -1) {
- fdctrl->dma_en = 1;
- DMA_register_channel(dma_chann, &fdctrl_transfer_handler, fdctrl);
- } else {
- fdctrl->dma_en = 0;
- }
- for (i = 0; i < 2; i++) {
- fd_init(&fdctrl->drives[i], fds[i]);
- if (fds[i]) {
- bdrv_set_change_cb(fds[i],
- &fd_change_cb, &fdctrl->drives[i]);
- }
- }
- fdctrl_reset(fdctrl, 0);
- fdctrl->state = FD_CTRL_ACTIVE;
- if (mem_mapped) {
- FLOPPY_ERROR("memory mapped floppy not supported by now !\n");
-#if 0
- io_mem = cpu_register_io_memory(0, fdctrl_mem_read, fdctrl_mem_write);
- cpu_register_physical_memory(base, 0x08, io_mem);
-#endif
- } else {
- register_ioport_read(io_base + 0x01, 5, 1, &fdctrl_read, fdctrl);
- register_ioport_read(io_base + 0x07, 1, 1, &fdctrl_read, fdctrl);
- register_ioport_write(io_base + 0x01, 5, 1, &fdctrl_write, fdctrl);
- register_ioport_write(io_base + 0x07, 1, 1, &fdctrl_write, fdctrl);
- }
- for (i = 0; i < 2; i++) {
- fd_revalidate(&fdctrl->drives[i]);
- }
-
- return fdctrl;
-}
-
-/* XXX: may change if moved to bdrv */
-int fdctrl_get_drive_type(fdctrl_t *fdctrl, int drive_num)
-{
- return fdctrl->drives[drive_num].drive;
-}
-
-/* Change IRQ state */
-static void fdctrl_reset_irq (fdctrl_t *fdctrl)
-{
- FLOPPY_DPRINTF("Reset interrupt\n");
- pic_set_irq(fdctrl->irq_lvl, 0);
- fdctrl->state &= ~FD_CTRL_INTR;
-}
-
-static void fdctrl_raise_irq (fdctrl_t *fdctrl, uint8_t status)
-{
- if (~(fdctrl->state & FD_CTRL_INTR)) {
- pic_set_irq(fdctrl->irq_lvl, 1);
- fdctrl->state |= FD_CTRL_INTR;
- }
- FLOPPY_DPRINTF("Set interrupt status to 0x%02x\n", status);
- fdctrl->int_status = status;
-}
-
-/* Reset controller */
-static void fdctrl_reset (fdctrl_t *fdctrl, int do_irq)
-{
- int i;
-
- FLOPPY_DPRINTF("reset controller\n");
- fdctrl_reset_irq(fdctrl);
- /* Initialise controller */
- fdctrl->cur_drv = 0;
- /* FIFO state */
- fdctrl->data_pos = 0;
- fdctrl->data_len = 0;
- fdctrl->data_state = FD_STATE_CMD;
- fdctrl->data_dir = FD_DIR_WRITE;
- for (i = 0; i < MAX_FD; i++)
- fd_reset(&fdctrl->drives[i]);
- fdctrl_reset_fifo(fdctrl);
- if (do_irq)
- fdctrl_raise_irq(fdctrl, 0xc0);
-}
-
-static inline fdrive_t *drv0 (fdctrl_t *fdctrl)
-{
- return &fdctrl->drives[fdctrl->bootsel];
-}
-
-static inline fdrive_t *drv1 (fdctrl_t *fdctrl)
-{
- return &fdctrl->drives[1 - fdctrl->bootsel];
-}
-
-static fdrive_t *get_cur_drv (fdctrl_t *fdctrl)
-{
- return fdctrl->cur_drv == 0 ? drv0(fdctrl) : drv1(fdctrl);
-}
-
-/* Status B register : 0x01 (read-only) */
-static uint32_t fdctrl_read_statusB (fdctrl_t *fdctrl)
-{
- FLOPPY_DPRINTF("status register: 0x00\n");
- return 0;
-}
-
-/* Digital output register : 0x02 */
-static uint32_t fdctrl_read_dor (fdctrl_t *fdctrl)
-{
- uint32_t retval = 0;
-
- /* Drive motors state indicators */
- if (drv0(fdctrl)->drflags & FDRIVE_MOTOR_ON)
- retval |= 1 << 5;
- if (drv1(fdctrl)->drflags & FDRIVE_MOTOR_ON)
- retval |= 1 << 4;
- /* DMA enable */
- retval |= fdctrl->dma_en << 3;
- /* Reset indicator */
- retval |= (fdctrl->state & FD_CTRL_RESET) == 0 ? 0x04 : 0;
- /* Selected drive */
- retval |= fdctrl->cur_drv;
- FLOPPY_DPRINTF("digital output register: 0x%02x\n", retval);
-
- return retval;
-}
-
-static void fdctrl_write_dor (fdctrl_t *fdctrl, uint32_t value)
-{
- /* Reset mode */
- if (fdctrl->state & FD_CTRL_RESET) {
- if (!(value & 0x04)) {
- FLOPPY_DPRINTF("Floppy controller in RESET state !\n");
- return;
- }
- }
- FLOPPY_DPRINTF("digital output register set to 0x%02x\n", value);
- /* Drive motors state indicators */
- if (value & 0x20)
- fd_start(drv1(fdctrl));
- else
- fd_stop(drv1(fdctrl));
- if (value & 0x10)
- fd_start(drv0(fdctrl));
- else
- fd_stop(drv0(fdctrl));
- /* DMA enable */
-#if 0
- if (fdctrl->dma_chann != -1)
- fdctrl->dma_en = 1 - ((value >> 3) & 1);
-#endif
- /* Reset */
- if (!(value & 0x04)) {
- if (!(fdctrl->state & FD_CTRL_RESET)) {
- FLOPPY_DPRINTF("controller enter RESET state\n");
- fdctrl->state |= FD_CTRL_RESET;
- }
- } else {
- if (fdctrl->state & FD_CTRL_RESET) {
- FLOPPY_DPRINTF("controller out of RESET state\n");
- fdctrl_reset(fdctrl, 1);
- fdctrl->state &= ~(FD_CTRL_RESET | FD_CTRL_SLEEP);
- }
- }
- /* Selected drive */
- fdctrl->cur_drv = value & 1;
-}
-
-/* Tape drive register : 0x03 */
-static uint32_t fdctrl_read_tape (fdctrl_t *fdctrl)
-{
- uint32_t retval = 0;
-
- /* Disk boot selection indicator */
- retval |= fdctrl->bootsel << 2;
- /* Tape indicators: never allowed */
- FLOPPY_DPRINTF("tape drive register: 0x%02x\n", retval);
-
- return retval;
-}
-
-static void fdctrl_write_tape (fdctrl_t *fdctrl, uint32_t value)
-{
- /* Reset mode */
- if (fdctrl->state & FD_CTRL_RESET) {
- FLOPPY_DPRINTF("Floppy controller in RESET state !\n");
- return;
- }
- FLOPPY_DPRINTF("tape drive register set to 0x%02x\n", value);
- /* Disk boot selection indicator */
- fdctrl->bootsel = (value >> 2) & 1;
- /* Tape indicators: never allow */
-}
-
-/* Main status register : 0x04 (read) */
-static uint32_t fdctrl_read_main_status (fdctrl_t *fdctrl)
-{
- uint32_t retval = 0;
-
- fdctrl->state &= ~(FD_CTRL_SLEEP | FD_CTRL_RESET);
- if (!(fdctrl->state & FD_CTRL_BUSY)) {
- /* Data transfer allowed */
- retval |= 0x80;
- /* Data transfer direction indicator */
- if (fdctrl->data_dir == FD_DIR_READ)
- retval |= 0x40;
- }
- /* Should handle 0x20 for SPECIFY command */
- /* Command busy indicator */
- if (FD_STATE(fdctrl->data_state) == FD_STATE_DATA ||
- FD_STATE(fdctrl->data_state) == FD_STATE_STATUS)
- retval |= 0x10;
- FLOPPY_DPRINTF("main status register: 0x%02x\n", retval);
-
- return retval;
-}
-
-/* Data select rate register : 0x04 (write) */
-static void fdctrl_write_rate (fdctrl_t *fdctrl, uint32_t value)
-{
- /* Reset mode */
- if (fdctrl->state & FD_CTRL_RESET) {
- FLOPPY_DPRINTF("Floppy controller in RESET state !\n");
- return;
- }
- FLOPPY_DPRINTF("select rate register set to 0x%02x\n", value);
- /* Reset: autoclear */
- if (value & 0x80) {
- fdctrl->state |= FD_CTRL_RESET;
- fdctrl_reset(fdctrl, 1);
- fdctrl->state &= ~FD_CTRL_RESET;
- }
- if (value & 0x40) {
- fdctrl->state |= FD_CTRL_SLEEP;
- fdctrl_reset(fdctrl, 1);
- }
-// fdctrl.precomp = (value >> 2) & 0x07;
-}
-
-/* Digital input register : 0x07 (read-only) */
-static uint32_t fdctrl_read_dir (fdctrl_t *fdctrl)
-{
- uint32_t retval = 0;
-
- if (drv0(fdctrl)->drflags & FDRIVE_REVALIDATE ||
- drv1(fdctrl)->drflags & FDRIVE_REVALIDATE)
- retval |= 0x80;
- if (retval != 0)
- FLOPPY_DPRINTF("Floppy digital input register: 0x%02x\n", retval);
- drv0(fdctrl)->drflags &= ~FDRIVE_REVALIDATE;
- drv1(fdctrl)->drflags &= ~FDRIVE_REVALIDATE;
-
- return retval;
-}
-
-/* FIFO state control */
-static void fdctrl_reset_fifo (fdctrl_t *fdctrl)
-{
- fdctrl->data_dir = FD_DIR_WRITE;
- fdctrl->data_pos = 0;
- FD_SET_STATE(fdctrl->data_state, FD_STATE_CMD);
-}
-
-/* Set FIFO status for the host to read */
-static void fdctrl_set_fifo (fdctrl_t *fdctrl, int fifo_len, int do_irq)
-{
- fdctrl->data_dir = FD_DIR_READ;
- fdctrl->data_len = fifo_len;
- fdctrl->data_pos = 0;
- FD_SET_STATE(fdctrl->data_state, FD_STATE_STATUS);
- if (do_irq)
- fdctrl_raise_irq(fdctrl, 0x00);
-}
-
-/* Set an error: unimplemented/unknown command */
-static void fdctrl_unimplemented (fdctrl_t *fdctrl)
-{
-#if 0
- fdrive_t *cur_drv;
-
- cur_drv = get_cur_drv(fdctrl);
- fdctrl->fifo[0] = 0x60 | (cur_drv->head << 2) | fdctrl->cur_drv;
- fdctrl->fifo[1] = 0x00;
- fdctrl->fifo[2] = 0x00;
- fdctrl_set_fifo(fdctrl, 3, 1);
-#else
- // fdctrl_reset_fifo(fdctrl);
- fdctrl->fifo[0] = 0x80;
- fdctrl_set_fifo(fdctrl, 1, 0);
-#endif
-}
-
-/* Callback for transfer end (stop or abort) */
-static void fdctrl_stop_transfer (fdctrl_t *fdctrl, uint8_t status0,
- uint8_t status1, uint8_t status2)
-{
- fdrive_t *cur_drv;
-
- cur_drv = get_cur_drv(fdctrl);
- FLOPPY_DPRINTF("transfer status: %02x %02x %02x (%02x)\n",
- status0, status1, status2,
- status0 | (cur_drv->head << 2) | fdctrl->cur_drv);
- fdctrl->fifo[0] = status0 | (cur_drv->head << 2) | fdctrl->cur_drv;
- fdctrl->fifo[1] = status1;
- fdctrl->fifo[2] = status2;
- fdctrl->fifo[3] = cur_drv->track;
- fdctrl->fifo[4] = cur_drv->head;
- fdctrl->fifo[5] = cur_drv->sect;
- fdctrl->fifo[6] = FD_SECTOR_SC;
- fdctrl->data_dir = FD_DIR_READ;
- if (fdctrl->state & FD_CTRL_BUSY) {
- DMA_release_DREQ(fdctrl->dma_chann);
- fdctrl->state &= ~FD_CTRL_BUSY;
- }
- fdctrl_set_fifo(fdctrl, 7, 1);
-}
-
-/* Prepare a data transfer (either DMA or FIFO) */
-static void fdctrl_start_transfer (fdctrl_t *fdctrl, int direction)
-{
- fdrive_t *cur_drv;
- uint8_t kh, kt, ks;
- int did_seek;
-
- fdctrl->cur_drv = fdctrl->fifo[1] & 1;
- cur_drv = get_cur_drv(fdctrl);
- kt = fdctrl->fifo[2];
- kh = fdctrl->fifo[3];
- ks = fdctrl->fifo[4];
- FLOPPY_DPRINTF("Start transfer at %d %d %02x %02x (%d)\n",
- fdctrl->cur_drv, kh, kt, ks,
- _fd_sector(kh, kt, ks, cur_drv->last_sect));
- did_seek = 0;
- switch (fd_seek(cur_drv, kh, kt, ks, fdctrl->config & 0x40)) {
- case 2:
- /* sect too big */
- fdctrl_stop_transfer(fdctrl, 0x40, 0x00, 0x00);
- fdctrl->fifo[3] = kt;
- fdctrl->fifo[4] = kh;
- fdctrl->fifo[5] = ks;
- return;
- case 3:
- /* track too big */
- fdctrl_stop_transfer(fdctrl, 0x40, 0x80, 0x00);
- fdctrl->fifo[3] = kt;
- fdctrl->fifo[4] = kh;
- fdctrl->fifo[5] = ks;
- return;
- case 4:
- /* No seek enabled */
- fdctrl_stop_transfer(fdctrl, 0x40, 0x00, 0x00);
- fdctrl->fifo[3] = kt;
- fdctrl->fifo[4] = kh;
- fdctrl->fifo[5] = ks;
- return;
- case 1:
- did_seek = 1;
- break;
- default:
- break;
- }
- /* Set the FIFO state */
- fdctrl->data_dir = direction;
- fdctrl->data_pos = 0;
- FD_SET_STATE(fdctrl->data_state, FD_STATE_DATA); /* FIFO ready for data */
- if (fdctrl->fifo[0] & 0x80)
- fdctrl->data_state |= FD_STATE_MULTI;
- else
- fdctrl->data_state &= ~FD_STATE_MULTI;
- if (did_seek)
- fdctrl->data_state |= FD_STATE_SEEK;
- else
- fdctrl->data_state &= ~FD_STATE_SEEK;
- if (fdctrl->fifo[5] == 00) {
- fdctrl->data_len = fdctrl->fifo[8];
- } else {
- int tmp;
- fdctrl->data_len = 128 << fdctrl->fifo[5];
- tmp = (cur_drv->last_sect - ks + 1);
- if (fdctrl->fifo[0] & 0x80)
- tmp += cur_drv->last_sect;
- fdctrl->data_len *= tmp;
- }
- fdctrl->eot = fdctrl->fifo[6];
- if (fdctrl->dma_en) {
- int dma_mode;
- /* DMA transfer are enabled. Check if DMA channel is well programmed */
- dma_mode = DMA_get_channel_mode(fdctrl->dma_chann);
- dma_mode = (dma_mode >> 2) & 3;
- FLOPPY_DPRINTF("dma_mode=%d direction=%d (%d - %d)\n",
- dma_mode, direction,
- (128 << fdctrl->fifo[5]) *
- (cur_drv->last_sect - ks + 1), fdctrl->data_len);
- if (((direction == FD_DIR_SCANE || direction == FD_DIR_SCANL ||
- direction == FD_DIR_SCANH) && dma_mode == 0) ||
- (direction == FD_DIR_WRITE && dma_mode == 2) ||
- (direction == FD_DIR_READ && dma_mode == 1)) {
- /* No access is allowed until DMA transfer has completed */
- fdctrl->state |= FD_CTRL_BUSY;
- /* Now, we just have to wait for the DMA controller to
- * recall us...
- */
- DMA_hold_DREQ(fdctrl->dma_chann);
- DMA_schedule(fdctrl->dma_chann);
- return;
- } else {
- FLOPPY_ERROR("dma_mode=%d direction=%d\n", dma_mode, direction);
- }
- }
- FLOPPY_DPRINTF("start non-DMA transfer\n");
- /* IO based transfer: calculate len */
- fdctrl_raise_irq(fdctrl, 0x00);
-
- return;
-}
-
-/* Prepare a transfer of deleted data */
-static void fdctrl_start_transfer_del (fdctrl_t *fdctrl, int direction)
-{
- /* We don't handle deleted data,
- * so we don't return *ANYTHING*
- */
- fdctrl_stop_transfer(fdctrl, 0x60, 0x00, 0x00);
-}
-
-/* handlers for DMA transfers */
-static int fdctrl_transfer_handler (void *opaque, int nchan,
- int dma_pos, int dma_len)
-{
- fdctrl_t *fdctrl;
- fdrive_t *cur_drv;
- int len, start_pos, rel_pos;
- uint8_t status0 = 0x00, status1 = 0x00, status2 = 0x00;
-
- fdctrl = opaque;
- if (!(fdctrl->state & FD_CTRL_BUSY)) {
- FLOPPY_DPRINTF("Not in DMA transfer mode !\n");
- return 0;
- }
- cur_drv = get_cur_drv(fdctrl);
- if (fdctrl->data_dir == FD_DIR_SCANE || fdctrl->data_dir == FD_DIR_SCANL ||
- fdctrl->data_dir == FD_DIR_SCANH)
- status2 = 0x04;
- if (dma_len > fdctrl->data_len)
- dma_len = fdctrl->data_len;
- if (cur_drv->bs == NULL) {
- if (fdctrl->data_dir == FD_DIR_WRITE)
- fdctrl_stop_transfer(fdctrl, 0x60, 0x00, 0x00);
- else
- fdctrl_stop_transfer(fdctrl, 0x40, 0x00, 0x00);
- len = 0;
- goto transfer_error;
- }
- rel_pos = fdctrl->data_pos % FD_SECTOR_LEN;
- for (start_pos = fdctrl->data_pos; fdctrl->data_pos < dma_len;) {
- len = dma_len - fdctrl->data_pos;
- if (len + rel_pos > FD_SECTOR_LEN)
- len = FD_SECTOR_LEN - rel_pos;
- FLOPPY_DPRINTF("copy %d bytes (%d %d %d) %d pos %d %02x %02x "
- "(%d-0x%08x 0x%08x)\n", len, size, fdctrl->data_pos,
- fdctrl->data_len, fdctrl->cur_drv, cur_drv->head,
- cur_drv->track, cur_drv->sect, fd_sector(cur_drv),
- fd_sector(cur_drv) * 512, addr);
- if (fdctrl->data_dir != FD_DIR_WRITE ||
- len < FD_SECTOR_LEN || rel_pos != 0) {
- /* READ & SCAN commands and realign to a sector for WRITE */
- if (bdrv_read(cur_drv->bs, fd_sector(cur_drv),
- fdctrl->fifo, 1) < 0) {
- FLOPPY_DPRINTF("Floppy: error getting sector %d\n",
- fd_sector(cur_drv));
- /* Sure, image size is too small... */
- memset(fdctrl->fifo, 0, FD_SECTOR_LEN);
- }
- }
- switch (fdctrl->data_dir) {
- case FD_DIR_READ:
- /* READ commands */
- DMA_write_memory (nchan, fdctrl->fifo + rel_pos,
- fdctrl->data_pos, len);
-/* cpu_physical_memory_write(addr + fdctrl->data_pos, */
-/* fdctrl->fifo + rel_pos, len); */
- break;
- case FD_DIR_WRITE:
- /* WRITE commands */
- DMA_read_memory (nchan, fdctrl->fifo + rel_pos,
- fdctrl->data_pos, len);
-/* cpu_physical_memory_read(addr + fdctrl->data_pos, */
-/* fdctrl->fifo + rel_pos, len); */
- if (bdrv_write(cur_drv->bs, fd_sector(cur_drv),
- fdctrl->fifo, 1) < 0) {
- FLOPPY_ERROR("writting sector %d\n", fd_sector(cur_drv));
- fdctrl_stop_transfer(fdctrl, 0x60, 0x00, 0x00);
- goto transfer_error;
- }
- break;
- default:
- /* SCAN commands */
- {
- uint8_t tmpbuf[FD_SECTOR_LEN];
- int ret;
- DMA_read_memory (nchan, tmpbuf, fdctrl->data_pos, len);
-/* cpu_physical_memory_read(addr + fdctrl->data_pos, */
-/* tmpbuf, len); */
- ret = memcmp(tmpbuf, fdctrl->fifo + rel_pos, len);
- if (ret == 0) {
- status2 = 0x08;
- goto end_transfer;
- }
- if ((ret < 0 && fdctrl->data_dir == FD_DIR_SCANL) ||
- (ret > 0 && fdctrl->data_dir == FD_DIR_SCANH)) {
- status2 = 0x00;
- goto end_transfer;
- }
- }
- break;
- }
- fdctrl->data_pos += len;
- rel_pos = fdctrl->data_pos % FD_SECTOR_LEN;
- if (rel_pos == 0) {
- /* Seek to next sector */
- FLOPPY_DPRINTF("seek to next sector (%d %02x %02x => %d) (%d)\n",
- cur_drv->head, cur_drv->track, cur_drv->sect,
- fd_sector(cur_drv),
- fdctrl->data_pos - size);
- /* XXX: cur_drv->sect >= cur_drv->last_sect should be an
- error in fact */
- if (cur_drv->sect >= cur_drv->last_sect ||
- cur_drv->sect == fdctrl->eot) {
- cur_drv->sect = 1;
- if (FD_MULTI_TRACK(fdctrl->data_state)) {
- if (cur_drv->head == 0 &&
- (cur_drv->flags & FDISK_DBL_SIDES) != 0) {
- cur_drv->head = 1;
- } else {
- cur_drv->head = 0;
- cur_drv->track++;
- if ((cur_drv->flags & FDISK_DBL_SIDES) == 0)
- break;
- }
- } else {
- cur_drv->track++;
- break;
- }
- FLOPPY_DPRINTF("seek to next track (%d %02x %02x => %d)\n",
- cur_drv->head, cur_drv->track,
- cur_drv->sect, fd_sector(cur_drv));
- } else {
- cur_drv->sect++;
- }
- }
- }
-end_transfer:
- len = fdctrl->data_pos - start_pos;
- FLOPPY_DPRINTF("end transfer %d %d %d\n",
- fdctrl->data_pos, len, fdctrl->data_len);
- if (fdctrl->data_dir == FD_DIR_SCANE ||
- fdctrl->data_dir == FD_DIR_SCANL ||
- fdctrl->data_dir == FD_DIR_SCANH)
- status2 = 0x08;
- if (FD_DID_SEEK(fdctrl->data_state))
- status0 |= 0x20;
- fdctrl->data_len -= len;
- // if (fdctrl->data_len == 0)
- fdctrl_stop_transfer(fdctrl, status0, status1, status2);
-transfer_error:
-
- return len;
-}
-
-/* Data register : 0x05 */
-static uint32_t fdctrl_read_data (fdctrl_t *fdctrl)
-{
- fdrive_t *cur_drv;
- uint32_t retval = 0;
- int pos, len;
-
- cur_drv = get_cur_drv(fdctrl);
- fdctrl->state &= ~FD_CTRL_SLEEP;
- if (FD_STATE(fdctrl->data_state) == FD_STATE_CMD) {
- FLOPPY_ERROR("can't read data in CMD state\n");
- return 0;
- }
- pos = fdctrl->data_pos;
- if (FD_STATE(fdctrl->data_state) == FD_STATE_DATA) {
- pos %= FD_SECTOR_LEN;
- if (pos == 0) {
- len = fdctrl->data_len - fdctrl->data_pos;
- if (len > FD_SECTOR_LEN)
- len = FD_SECTOR_LEN;
- bdrv_read(cur_drv->bs, fd_sector(cur_drv),
- fdctrl->fifo, len);
- }
- }
- retval = fdctrl->fifo[pos];
- if (++fdctrl->data_pos == fdctrl->data_len) {
- fdctrl->data_pos = 0;
- /* Switch from transfer mode to status mode
- * then from status mode to command mode
- */
- if (FD_STATE(fdctrl->data_state) == FD_STATE_DATA) {
- fdctrl_stop_transfer(fdctrl, 0x20, 0x00, 0x00);
- } else {
- fdctrl_reset_fifo(fdctrl);
- fdctrl_reset_irq(fdctrl);
- }
- }
- FLOPPY_DPRINTF("data register: 0x%02x\n", retval);
-
- return retval;
-}
-
-static void fdctrl_format_sector (fdctrl_t *fdctrl)
-{
- fdrive_t *cur_drv;
- uint8_t kh, kt, ks;
- int did_seek;
-
- fdctrl->cur_drv = fdctrl->fifo[1] & 1;
- cur_drv = get_cur_drv(fdctrl);
- kt = fdctrl->fifo[6];
- kh = fdctrl->fifo[7];
- ks = fdctrl->fifo[8];
- FLOPPY_DPRINTF("format sector at %d %d %02x %02x (%d)\n",
- fdctrl->cur_drv, kh, kt, ks,
- _fd_sector(kh, kt, ks, cur_drv->last_sect));
- did_seek = 0;
- switch (fd_seek(cur_drv, kh, kt, ks, fdctrl->config & 0x40)) {
- case 2:
- /* sect too big */
- fdctrl_stop_transfer(fdctrl, 0x40, 0x00, 0x00);
- fdctrl->fifo[3] = kt;
- fdctrl->fifo[4] = kh;
- fdctrl->fifo[5] = ks;
- return;
- case 3:
- /* track too big */
- fdctrl_stop_transfer(fdctrl, 0x40, 0x80, 0x00);
- fdctrl->fifo[3] = kt;
- fdctrl->fifo[4] = kh;
- fdctrl->fifo[5] = ks;
- return;
- case 4:
- /* No seek enabled */
- fdctrl_stop_transfer(fdctrl, 0x40, 0x00, 0x00);
- fdctrl->fifo[3] = kt;
- fdctrl->fifo[4] = kh;
- fdctrl->fifo[5] = ks;
- return;
- case 1:
- did_seek = 1;
- fdctrl->data_state |= FD_STATE_SEEK;
- break;
- default:
- break;
- }
- memset(fdctrl->fifo, 0, FD_SECTOR_LEN);
- if (cur_drv->bs == NULL ||
- bdrv_write(cur_drv->bs, fd_sector(cur_drv), fdctrl->fifo, 1) < 0) {
- FLOPPY_ERROR("formating sector %d\n", fd_sector(cur_drv));
- fdctrl_stop_transfer(fdctrl, 0x60, 0x00, 0x00);
- } else {
- if (cur_drv->sect == cur_drv->last_sect) {
- fdctrl->data_state &= ~FD_STATE_FORMAT;
- /* Last sector done */
- if (FD_DID_SEEK(fdctrl->data_state))
- fdctrl_stop_transfer(fdctrl, 0x20, 0x00, 0x00);
- else
- fdctrl_stop_transfer(fdctrl, 0x00, 0x00, 0x00);
- } else {
- /* More to do */
- fdctrl->data_pos = 0;
- fdctrl->data_len = 4;
- }
- }
-}
-
-static void fdctrl_write_data (fdctrl_t *fdctrl, uint32_t value)
-{
- fdrive_t *cur_drv;
-
- cur_drv = get_cur_drv(fdctrl);
- /* Reset mode */
- if (fdctrl->state & FD_CTRL_RESET) {
- FLOPPY_DPRINTF("Floppy controller in RESET state !\n");
- return;
- }
- fdctrl->state &= ~FD_CTRL_SLEEP;
- if (FD_STATE(fdctrl->data_state) == FD_STATE_STATUS) {
- FLOPPY_ERROR("can't write data in status mode\n");
- return;
- }
- /* Is it write command time ? */
- if (FD_STATE(fdctrl->data_state) == FD_STATE_DATA) {
- /* FIFO data write */
- fdctrl->fifo[fdctrl->data_pos++] = value;
- if (fdctrl->data_pos % FD_SECTOR_LEN == (FD_SECTOR_LEN - 1) ||
- fdctrl->data_pos == fdctrl->data_len) {
- bdrv_write(cur_drv->bs, fd_sector(cur_drv),
- fdctrl->fifo, FD_SECTOR_LEN);
- }
- /* Switch from transfer mode to status mode
- * then from status mode to command mode
- */
- if (FD_STATE(fdctrl->data_state) == FD_STATE_DATA)
- fdctrl_stop_transfer(fdctrl, 0x20, 0x00, 0x00);
- return;
- }
- if (fdctrl->data_pos == 0) {
- /* Command */
- switch (value & 0x5F) {
- case 0x46:
- /* READ variants */
- FLOPPY_DPRINTF("READ command\n");
- /* 8 parameters cmd */
- fdctrl->data_len = 9;
- goto enqueue;
- case 0x4C:
- /* READ_DELETED variants */
- FLOPPY_DPRINTF("READ_DELETED command\n");
- /* 8 parameters cmd */
- fdctrl->data_len = 9;
- goto enqueue;
- case 0x50:
- /* SCAN_EQUAL variants */
- FLOPPY_DPRINTF("SCAN_EQUAL command\n");
- /* 8 parameters cmd */
- fdctrl->data_len = 9;
- goto enqueue;
- case 0x56:
- /* VERIFY variants */
- FLOPPY_DPRINTF("VERIFY command\n");
- /* 8 parameters cmd */
- fdctrl->data_len = 9;
- goto enqueue;
- case 0x59:
- /* SCAN_LOW_OR_EQUAL variants */
- FLOPPY_DPRINTF("SCAN_LOW_OR_EQUAL command\n");
- /* 8 parameters cmd */
- fdctrl->data_len = 9;
- goto enqueue;
- case 0x5D:
- /* SCAN_HIGH_OR_EQUAL variants */
- FLOPPY_DPRINTF("SCAN_HIGH_OR_EQUAL command\n");
- /* 8 parameters cmd */
- fdctrl->data_len = 9;
- goto enqueue;
- default:
- break;
- }
- switch (value & 0x7F) {
- case 0x45:
- /* WRITE variants */
- FLOPPY_DPRINTF("WRITE command\n");
- /* 8 parameters cmd */
- fdctrl->data_len = 9;
- goto enqueue;
- case 0x49:
- /* WRITE_DELETED variants */
- FLOPPY_DPRINTF("WRITE_DELETED command\n");
- /* 8 parameters cmd */
- fdctrl->data_len = 9;
- goto enqueue;
- default:
- break;
- }
- switch (value) {
- case 0x03:
- /* SPECIFY */
- FLOPPY_DPRINTF("SPECIFY command\n");
- /* 1 parameter cmd */
- fdctrl->data_len = 3;
- goto enqueue;
- case 0x04:
- /* SENSE_DRIVE_STATUS */
- FLOPPY_DPRINTF("SENSE_DRIVE_STATUS command\n");
- /* 1 parameter cmd */
- fdctrl->data_len = 2;
- goto enqueue;
- case 0x07:
- /* RECALIBRATE */
- FLOPPY_DPRINTF("RECALIBRATE command\n");
- /* 1 parameter cmd */
- fdctrl->data_len = 2;
- goto enqueue;
- case 0x08:
- /* SENSE_INTERRUPT_STATUS */
- FLOPPY_DPRINTF("SENSE_INTERRUPT_STATUS command (%02x)\n",
- fdctrl->int_status);
- /* No parameters cmd: returns status if no interrupt */
-#if 0
- fdctrl->fifo[0] =
- fdctrl->int_status | (cur_drv->head << 2) | fdctrl->cur_drv;
-#else
- /* XXX: int_status handling is broken for read/write
- commands, so we do this hack. It should be suppressed
- ASAP */
- fdctrl->fifo[0] =
- 0x20 | (cur_drv->head << 2) | fdctrl->cur_drv;
-#endif
- fdctrl->fifo[1] = cur_drv->track;
- fdctrl_set_fifo(fdctrl, 2, 0);
- fdctrl_reset_irq(fdctrl);
- fdctrl->int_status = 0xC0;
- return;
- case 0x0E:
- /* DUMPREG */
- FLOPPY_DPRINTF("DUMPREG command\n");
- /* Drives position */
- fdctrl->fifo[0] = drv0(fdctrl)->track;
- fdctrl->fifo[1] = drv1(fdctrl)->track;
- fdctrl->fifo[2] = 0;
- fdctrl->fifo[3] = 0;
- /* timers */
- fdctrl->fifo[4] = fdctrl->timer0;
- fdctrl->fifo[5] = (fdctrl->timer1 << 1) | fdctrl->dma_en;
- fdctrl->fifo[6] = cur_drv->last_sect;
- fdctrl->fifo[7] = (fdctrl->lock << 7) |
- (cur_drv->perpendicular << 2);
- fdctrl->fifo[8] = fdctrl->config;
- fdctrl->fifo[9] = fdctrl->precomp_trk;
- fdctrl_set_fifo(fdctrl, 10, 0);
- return;
- case 0x0F:
- /* SEEK */
- FLOPPY_DPRINTF("SEEK command\n");
- /* 2 parameters cmd */
- fdctrl->data_len = 3;
- goto enqueue;
- case 0x10:
- /* VERSION */
- FLOPPY_DPRINTF("VERSION command\n");
- /* No parameters cmd */
- /* Controller's version */
- fdctrl->fifo[0] = fdctrl->version;
- fdctrl_set_fifo(fdctrl, 1, 1);
- return;
- case 0x12:
- /* PERPENDICULAR_MODE */
- FLOPPY_DPRINTF("PERPENDICULAR_MODE command\n");
- /* 1 parameter cmd */
- fdctrl->data_len = 2;
- goto enqueue;
- case 0x13:
- /* CONFIGURE */
- FLOPPY_DPRINTF("CONFIGURE command\n");
- /* 3 parameters cmd */
- fdctrl->data_len = 4;
- goto enqueue;
- case 0x14:
- /* UNLOCK */
- FLOPPY_DPRINTF("UNLOCK command\n");
- /* No parameters cmd */
- fdctrl->lock = 0;
- fdctrl->fifo[0] = 0;
- fdctrl_set_fifo(fdctrl, 1, 0);
- return;
- case 0x17:
- /* POWERDOWN_MODE */
- FLOPPY_DPRINTF("POWERDOWN_MODE command\n");
- /* 2 parameters cmd */
- fdctrl->data_len = 3;
- goto enqueue;
- case 0x18:
- /* PART_ID */
- FLOPPY_DPRINTF("PART_ID command\n");
- /* No parameters cmd */
- fdctrl->fifo[0] = 0x41; /* Stepping 1 */
- fdctrl_set_fifo(fdctrl, 1, 0);
- return;
- case 0x2C:
- /* SAVE */
- FLOPPY_DPRINTF("SAVE command\n");
- /* No parameters cmd */
- fdctrl->fifo[0] = 0;
- fdctrl->fifo[1] = 0;
- /* Drives position */
- fdctrl->fifo[2] = drv0(fdctrl)->track;
- fdctrl->fifo[3] = drv1(fdctrl)->track;
- fdctrl->fifo[4] = 0;
- fdctrl->fifo[5] = 0;
- /* timers */
- fdctrl->fifo[6] = fdctrl->timer0;
- fdctrl->fifo[7] = fdctrl->timer1;
- fdctrl->fifo[8] = cur_drv->last_sect;
- fdctrl->fifo[9] = (fdctrl->lock << 7) |
- (cur_drv->perpendicular << 2);
- fdctrl->fifo[10] = fdctrl->config;
- fdctrl->fifo[11] = fdctrl->precomp_trk;
- fdctrl->fifo[12] = fdctrl->pwrd;
- fdctrl->fifo[13] = 0;
- fdctrl->fifo[14] = 0;
- fdctrl_set_fifo(fdctrl, 15, 1);
- return;
- case 0x33:
- /* OPTION */
- FLOPPY_DPRINTF("OPTION command\n");
- /* 1 parameter cmd */
- fdctrl->data_len = 2;
- goto enqueue;
- case 0x42:
- /* READ_TRACK */
- FLOPPY_DPRINTF("READ_TRACK command\n");
- /* 8 parameters cmd */
- fdctrl->data_len = 9;
- goto enqueue;
- case 0x4A:
- /* READ_ID */
- FLOPPY_DPRINTF("READ_ID command\n");
- /* 1 parameter cmd */
- fdctrl->data_len = 2;
- goto enqueue;
- case 0x4C:
- /* RESTORE */
- FLOPPY_DPRINTF("RESTORE command\n");
- /* 17 parameters cmd */
- fdctrl->data_len = 18;
- goto enqueue;
- case 0x4D:
- /* FORMAT_TRACK */
- FLOPPY_DPRINTF("FORMAT_TRACK command\n");
- /* 5 parameters cmd */
- fdctrl->data_len = 6;
- goto enqueue;
- case 0x8E:
- /* DRIVE_SPECIFICATION_COMMAND */
- FLOPPY_DPRINTF("DRIVE_SPECIFICATION_COMMAND command\n");
- /* 5 parameters cmd */
- fdctrl->data_len = 6;
- goto enqueue;
- case 0x8F:
- /* RELATIVE_SEEK_OUT */
- FLOPPY_DPRINTF("RELATIVE_SEEK_OUT command\n");
- /* 2 parameters cmd */
- fdctrl->data_len = 3;
- goto enqueue;
- case 0x94:
- /* LOCK */
- FLOPPY_DPRINTF("LOCK command\n");
- /* No parameters cmd */
- fdctrl->lock = 1;
- fdctrl->fifo[0] = 0x10;
- fdctrl_set_fifo(fdctrl, 1, 1);
- return;
- case 0xCD:
- /* FORMAT_AND_WRITE */
- FLOPPY_DPRINTF("FORMAT_AND_WRITE command\n");
- /* 10 parameters cmd */
- fdctrl->data_len = 11;
- goto enqueue;
- case 0xCF:
- /* RELATIVE_SEEK_IN */
- FLOPPY_DPRINTF("RELATIVE_SEEK_IN command\n");
- /* 2 parameters cmd */
- fdctrl->data_len = 3;
- goto enqueue;
- default:
- /* Unknown command */
- FLOPPY_ERROR("unknown command: 0x%02x\n", value);
- fdctrl_unimplemented(fdctrl);
- return;
- }
- }
-enqueue:
- FLOPPY_DPRINTF("%s: %02x\n", __func__, value);
- fdctrl->fifo[fdctrl->data_pos] = value;
- if (++fdctrl->data_pos == fdctrl->data_len) {
- /* We now have all parameters
- * and will be able to treat the command
- */
- if (fdctrl->data_state & FD_STATE_FORMAT) {
- fdctrl_format_sector(fdctrl);
- return;
- }
- switch (fdctrl->fifo[0] & 0x1F) {
- case 0x06:
- {
- /* READ variants */
- FLOPPY_DPRINTF("treat READ command\n");
- fdctrl_start_transfer(fdctrl, FD_DIR_READ);
- return;
- }
- case 0x0C:
- /* READ_DELETED variants */
-// FLOPPY_DPRINTF("treat READ_DELETED command\n");
- FLOPPY_ERROR("treat READ_DELETED command\n");
- fdctrl_start_transfer_del(fdctrl, FD_DIR_READ);
- return;
- case 0x16:
- /* VERIFY variants */
-// FLOPPY_DPRINTF("treat VERIFY command\n");
- FLOPPY_ERROR("treat VERIFY command\n");
- fdctrl_stop_transfer(fdctrl, 0x20, 0x00, 0x00);
- return;
- case 0x10:
- /* SCAN_EQUAL variants */
-// FLOPPY_DPRINTF("treat SCAN_EQUAL command\n");
- FLOPPY_ERROR("treat SCAN_EQUAL command\n");
- fdctrl_start_transfer(fdctrl, FD_DIR_SCANE);
- return;
- case 0x19:
- /* SCAN_LOW_OR_EQUAL variants */
-// FLOPPY_DPRINTF("treat SCAN_LOW_OR_EQUAL command\n");
- FLOPPY_ERROR("treat SCAN_LOW_OR_EQUAL command\n");
- fdctrl_start_transfer(fdctrl, FD_DIR_SCANL);
- return;
- case 0x1D:
- /* SCAN_HIGH_OR_EQUAL variants */
-// FLOPPY_DPRINTF("treat SCAN_HIGH_OR_EQUAL command\n");
- FLOPPY_ERROR("treat SCAN_HIGH_OR_EQUAL command\n");
- fdctrl_start_transfer(fdctrl, FD_DIR_SCANH);
- return;
- default:
- break;
- }
- switch (fdctrl->fifo[0] & 0x3F) {
- case 0x05:
- /* WRITE variants */
- FLOPPY_DPRINTF("treat WRITE command (%02x)\n", fdctrl->fifo[0]);
- fdctrl_start_transfer(fdctrl, FD_DIR_WRITE);
- return;
- case 0x09:
- /* WRITE_DELETED variants */
-// FLOPPY_DPRINTF("treat WRITE_DELETED command\n");
- FLOPPY_ERROR("treat WRITE_DELETED command\n");
- fdctrl_start_transfer_del(fdctrl, FD_DIR_WRITE);
- return;
- default:
- break;
- }
- switch (fdctrl->fifo[0]) {
- case 0x03:
- /* SPECIFY */
- FLOPPY_DPRINTF("treat SPECIFY command\n");
- fdctrl->timer0 = (fdctrl->fifo[1] >> 4) & 0xF;
- fdctrl->timer1 = fdctrl->fifo[2] >> 1;
- fdctrl->dma_en = 1 - (fdctrl->fifo[2] & 1) ;
- /* No result back */
- fdctrl_reset_fifo(fdctrl);
- break;
- case 0x04:
- /* SENSE_DRIVE_STATUS */
- FLOPPY_DPRINTF("treat SENSE_DRIVE_STATUS command\n");
- fdctrl->cur_drv = fdctrl->fifo[1] & 1;
- cur_drv = get_cur_drv(fdctrl);
- cur_drv->head = (fdctrl->fifo[1] >> 2) & 1;
- /* 1 Byte status back */
- fdctrl->fifo[0] = (cur_drv->ro << 6) |
- (cur_drv->track == 0 ? 0x10 : 0x00) |
- (cur_drv->head << 2) |
- fdctrl->cur_drv |
- 0x28;
- fdctrl_set_fifo(fdctrl, 1, 0);
- break;
- case 0x07:
- /* RECALIBRATE */
- FLOPPY_DPRINTF("treat RECALIBRATE command\n");
- fdctrl->cur_drv = fdctrl->fifo[1] & 1;
- cur_drv = get_cur_drv(fdctrl);
- fd_recalibrate(cur_drv);
- fdctrl_reset_fifo(fdctrl);
- /* Raise Interrupt */
- fdctrl_raise_irq(fdctrl, 0x20);
- break;
- case 0x0F:
- /* SEEK */
- FLOPPY_DPRINTF("treat SEEK command\n");
- fdctrl->cur_drv = fdctrl->fifo[1] & 1;
- cur_drv = get_cur_drv(fdctrl);
- fd_start(cur_drv);
- if (fdctrl->fifo[2] <= cur_drv->track)
- cur_drv->dir = 1;
- else
- cur_drv->dir = 0;
- fdctrl_reset_fifo(fdctrl);
- if (fdctrl->fifo[2] > cur_drv->max_track) {
- fdctrl_raise_irq(fdctrl, 0x60);
- } else {
- cur_drv->track = fdctrl->fifo[2];
- /* Raise Interrupt */
- fdctrl_raise_irq(fdctrl, 0x20);
- }
- break;
- case 0x12:
- /* PERPENDICULAR_MODE */
- FLOPPY_DPRINTF("treat PERPENDICULAR_MODE command\n");
- if (fdctrl->fifo[1] & 0x80)
- cur_drv->perpendicular = fdctrl->fifo[1] & 0x7;
- /* No result back */
- fdctrl_reset_fifo(fdctrl);
- break;
- case 0x13:
- /* CONFIGURE */
- FLOPPY_DPRINTF("treat CONFIGURE command\n");
- fdctrl->config = fdctrl->fifo[2];
- fdctrl->precomp_trk = fdctrl->fifo[3];
- /* No result back */
- fdctrl_reset_fifo(fdctrl);
- break;
- case 0x17:
- /* POWERDOWN_MODE */
- FLOPPY_DPRINTF("treat POWERDOWN_MODE command\n");
- fdctrl->pwrd = fdctrl->fifo[1];
- fdctrl->fifo[0] = fdctrl->fifo[1];
- fdctrl_set_fifo(fdctrl, 1, 1);
- break;
- case 0x33:
- /* OPTION */
- FLOPPY_DPRINTF("treat OPTION command\n");
- /* No result back */
- fdctrl_reset_fifo(fdctrl);
- break;
- case 0x42:
- /* READ_TRACK */
-// FLOPPY_DPRINTF("treat READ_TRACK command\n");
- FLOPPY_ERROR("treat READ_TRACK command\n");
- fdctrl_start_transfer(fdctrl, FD_DIR_READ);
- break;
- case 0x4A:
- /* READ_ID */
- FLOPPY_DPRINTF("treat READ_ID command\n");
- /* XXX: should set main status register to busy */
- cur_drv->head = (fdctrl->fifo[1] >> 2) & 1;
- qemu_mod_timer(fdctrl->result_timer,
- qemu_get_clock(vm_clock) + (ticks_per_sec / 50));
- break;
- case 0x4C:
- /* RESTORE */
- FLOPPY_DPRINTF("treat RESTORE command\n");
- /* Drives position */
- drv0(fdctrl)->track = fdctrl->fifo[3];
- drv1(fdctrl)->track = fdctrl->fifo[4];
- /* timers */
- fdctrl->timer0 = fdctrl->fifo[7];
- fdctrl->timer1 = fdctrl->fifo[8];
- cur_drv->last_sect = fdctrl->fifo[9];
- fdctrl->lock = fdctrl->fifo[10] >> 7;
- cur_drv->perpendicular = (fdctrl->fifo[10] >> 2) & 0xF;
- fdctrl->config = fdctrl->fifo[11];
- fdctrl->precomp_trk = fdctrl->fifo[12];
- fdctrl->pwrd = fdctrl->fifo[13];
- fdctrl_reset_fifo(fdctrl);
- break;
- case 0x4D:
- /* FORMAT_TRACK */
- FLOPPY_DPRINTF("treat FORMAT_TRACK command\n");
- fdctrl->cur_drv = fdctrl->fifo[1] & 1;
- cur_drv = get_cur_drv(fdctrl);
- fdctrl->data_state |= FD_STATE_FORMAT;
- if (fdctrl->fifo[0] & 0x80)
- fdctrl->data_state |= FD_STATE_MULTI;
- else
- fdctrl->data_state &= ~FD_STATE_MULTI;
- fdctrl->data_state &= ~FD_STATE_SEEK;
- cur_drv->bps =
- fdctrl->fifo[2] > 7 ? 16384 : 128 << fdctrl->fifo[2];
-#if 0
- cur_drv->last_sect =
- cur_drv->flags & FDISK_DBL_SIDES ? fdctrl->fifo[3] :
- fdctrl->fifo[3] / 2;
-#else
- cur_drv->last_sect = fdctrl->fifo[3];
-#endif
- /* Bochs BIOS is buggy and don't send format informations
- * for each sector. So, pretend all's done right now...
- */
- fdctrl->data_state &= ~FD_STATE_FORMAT;
- fdctrl_stop_transfer(fdctrl, 0x00, 0x00, 0x00);
- break;
- case 0x8E:
- /* DRIVE_SPECIFICATION_COMMAND */
- FLOPPY_DPRINTF("treat DRIVE_SPECIFICATION_COMMAND command\n");
- if (fdctrl->fifo[fdctrl->data_pos - 1] & 0x80) {
- /* Command parameters done */
- if (fdctrl->fifo[fdctrl->data_pos - 1] & 0x40) {
- fdctrl->fifo[0] = fdctrl->fifo[1];
- fdctrl->fifo[2] = 0;
- fdctrl->fifo[3] = 0;
- fdctrl_set_fifo(fdctrl, 4, 1);
- } else {
- fdctrl_reset_fifo(fdctrl);
- }
- } else if (fdctrl->data_len > 7) {
- /* ERROR */
- fdctrl->fifo[0] = 0x80 |
- (cur_drv->head << 2) | fdctrl->cur_drv;
- fdctrl_set_fifo(fdctrl, 1, 1);
- }
- break;
- case 0x8F:
- /* RELATIVE_SEEK_OUT */
- FLOPPY_DPRINTF("treat RELATIVE_SEEK_OUT command\n");
- fdctrl->cur_drv = fdctrl->fifo[1] & 1;
- cur_drv = get_cur_drv(fdctrl);
- fd_start(cur_drv);
- cur_drv->dir = 0;
- if (fdctrl->fifo[2] + cur_drv->track >= cur_drv->max_track) {
- cur_drv->track = cur_drv->max_track - 1;
- } else {
- cur_drv->track += fdctrl->fifo[2];
- }
- fdctrl_reset_fifo(fdctrl);
- fdctrl_raise_irq(fdctrl, 0x20);
- break;
- case 0xCD:
- /* FORMAT_AND_WRITE */
-// FLOPPY_DPRINTF("treat FORMAT_AND_WRITE command\n");
- FLOPPY_ERROR("treat FORMAT_AND_WRITE command\n");
- fdctrl_unimplemented(fdctrl);
- break;
- case 0xCF:
- /* RELATIVE_SEEK_IN */
- FLOPPY_DPRINTF("treat RELATIVE_SEEK_IN command\n");
- fdctrl->cur_drv = fdctrl->fifo[1] & 1;
- cur_drv = get_cur_drv(fdctrl);
- fd_start(cur_drv);
- cur_drv->dir = 1;
- if (fdctrl->fifo[2] > cur_drv->track) {
- cur_drv->track = 0;
- } else {
- cur_drv->track -= fdctrl->fifo[2];
- }
- fdctrl_reset_fifo(fdctrl);
- /* Raise Interrupt */
- fdctrl_raise_irq(fdctrl, 0x20);
- break;
- }
- }
-}
-
-static void fdctrl_result_timer(void *opaque)
-{
- fdctrl_t *fdctrl = opaque;
- fdctrl_stop_transfer(fdctrl, 0x00, 0x00, 0x00);
-}
+++ /dev/null
-/*
-**
-** File: fmopl.c -- software implementation of FM sound generator
-**
-** Copyright (C) 1999,2000 Tatsuyuki Satoh , MultiArcadeMachineEmurator development
-**
-** Version 0.37a
-**
-*/
-
-/*
- preliminary :
- Problem :
- note:
-*/
-
-/* This version of fmopl.c is a fork of the MAME one, relicensed under the LGPL.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#define INLINE __inline
-#define HAS_YM3812 1
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdarg.h>
-#include <math.h>
-//#include "driver.h" /* use M.A.M.E. */
-#include "fmopl.h"
-
-#ifndef PI
-#define PI 3.14159265358979323846
-#endif
-
-/* -------------------- for debug --------------------- */
-/* #define OPL_OUTPUT_LOG */
-#ifdef OPL_OUTPUT_LOG
-static FILE *opl_dbg_fp = NULL;
-static FM_OPL *opl_dbg_opl[16];
-static int opl_dbg_maxchip,opl_dbg_chip;
-#endif
-
-/* -------------------- preliminary define section --------------------- */
-/* attack/decay rate time rate */
-#define OPL_ARRATE 141280 /* RATE 4 = 2826.24ms @ 3.6MHz */
-#define OPL_DRRATE 1956000 /* RATE 4 = 39280.64ms @ 3.6MHz */
-
-#define DELTAT_MIXING_LEVEL (1) /* DELTA-T ADPCM MIXING LEVEL */
-
-#define FREQ_BITS 24 /* frequency turn */
-
-/* counter bits = 20 , octerve 7 */
-#define FREQ_RATE (1<<(FREQ_BITS-20))
-#define TL_BITS (FREQ_BITS+2)
-
-/* final output shift , limit minimum and maximum */
-#define OPL_OUTSB (TL_BITS+3-16) /* OPL output final shift 16bit */
-#define OPL_MAXOUT (0x7fff<<OPL_OUTSB)
-#define OPL_MINOUT (-0x8000<<OPL_OUTSB)
-
-/* -------------------- quality selection --------------------- */
-
-/* sinwave entries */
-/* used static memory = SIN_ENT * 4 (byte) */
-#define SIN_ENT 2048
-
-/* output level entries (envelope,sinwave) */
-/* envelope counter lower bits */
-#define ENV_BITS 16
-/* envelope output entries */
-#define EG_ENT 4096
-/* used dynamic memory = EG_ENT*4*4(byte)or EG_ENT*6*4(byte) */
-/* used static memory = EG_ENT*4 (byte) */
-
-#define EG_OFF ((2*EG_ENT)<<ENV_BITS) /* OFF */
-#define EG_DED EG_OFF
-#define EG_DST (EG_ENT<<ENV_BITS) /* DECAY START */
-#define EG_AED EG_DST
-#define EG_AST 0 /* ATTACK START */
-
-#define EG_STEP (96.0/EG_ENT) /* OPL is 0.1875 dB step */
-
-/* LFO table entries */
-#define VIB_ENT 512
-#define VIB_SHIFT (32-9)
-#define AMS_ENT 512
-#define AMS_SHIFT (32-9)
-
-#define VIB_RATE 256
-
-/* -------------------- local defines , macros --------------------- */
-
-/* register number to channel number , slot offset */
-#define SLOT1 0
-#define SLOT2 1
-
-/* envelope phase */
-#define ENV_MOD_RR 0x00
-#define ENV_MOD_DR 0x01
-#define ENV_MOD_AR 0x02
-
-/* -------------------- tables --------------------- */
-static const int slot_array[32]=
-{
- 0, 2, 4, 1, 3, 5,-1,-1,
- 6, 8,10, 7, 9,11,-1,-1,
- 12,14,16,13,15,17,-1,-1,
- -1,-1,-1,-1,-1,-1,-1,-1
-};
-
-/* key scale level */
-/* table is 3dB/OCT , DV converts this in TL step at 6dB/OCT */
-#define DV (EG_STEP/2)
-static const UINT32 KSL_TABLE[8*16]=
-{
- /* OCT 0 */
- 0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV,
- 0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV,
- 0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV,
- 0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV,
- /* OCT 1 */
- 0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV,
- 0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV,
- 0.000/DV, 0.750/DV, 1.125/DV, 1.500/DV,
- 1.875/DV, 2.250/DV, 2.625/DV, 3.000/DV,
- /* OCT 2 */
- 0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV,
- 0.000/DV, 1.125/DV, 1.875/DV, 2.625/DV,
- 3.000/DV, 3.750/DV, 4.125/DV, 4.500/DV,
- 4.875/DV, 5.250/DV, 5.625/DV, 6.000/DV,
- /* OCT 3 */
- 0.000/DV, 0.000/DV, 0.000/DV, 1.875/DV,
- 3.000/DV, 4.125/DV, 4.875/DV, 5.625/DV,
- 6.000/DV, 6.750/DV, 7.125/DV, 7.500/DV,
- 7.875/DV, 8.250/DV, 8.625/DV, 9.000/DV,
- /* OCT 4 */
- 0.000/DV, 0.000/DV, 3.000/DV, 4.875/DV,
- 6.000/DV, 7.125/DV, 7.875/DV, 8.625/DV,
- 9.000/DV, 9.750/DV,10.125/DV,10.500/DV,
- 10.875/DV,11.250/DV,11.625/DV,12.000/DV,
- /* OCT 5 */
- 0.000/DV, 3.000/DV, 6.000/DV, 7.875/DV,
- 9.000/DV,10.125/DV,10.875/DV,11.625/DV,
- 12.000/DV,12.750/DV,13.125/DV,13.500/DV,
- 13.875/DV,14.250/DV,14.625/DV,15.000/DV,
- /* OCT 6 */
- 0.000/DV, 6.000/DV, 9.000/DV,10.875/DV,
- 12.000/DV,13.125/DV,13.875/DV,14.625/DV,
- 15.000/DV,15.750/DV,16.125/DV,16.500/DV,
- 16.875/DV,17.250/DV,17.625/DV,18.000/DV,
- /* OCT 7 */
- 0.000/DV, 9.000/DV,12.000/DV,13.875/DV,
- 15.000/DV,16.125/DV,16.875/DV,17.625/DV,
- 18.000/DV,18.750/DV,19.125/DV,19.500/DV,
- 19.875/DV,20.250/DV,20.625/DV,21.000/DV
-};
-#undef DV
-
-/* sustain lebel table (3db per step) */
-/* 0 - 15: 0, 3, 6, 9,12,15,18,21,24,27,30,33,36,39,42,93 (dB)*/
-#define SC(db) (db*((3/EG_STEP)*(1<<ENV_BITS)))+EG_DST
-static const INT32 SL_TABLE[16]={
- SC( 0),SC( 1),SC( 2),SC(3 ),SC(4 ),SC(5 ),SC(6 ),SC( 7),
- SC( 8),SC( 9),SC(10),SC(11),SC(12),SC(13),SC(14),SC(31)
-};
-#undef SC
-
-#define TL_MAX (EG_ENT*2) /* limit(tl + ksr + envelope) + sinwave */
-/* TotalLevel : 48 24 12 6 3 1.5 0.75 (dB) */
-/* TL_TABLE[ 0 to TL_MAX ] : plus section */
-/* TL_TABLE[ TL_MAX to TL_MAX+TL_MAX-1 ] : minus section */
-static INT32 *TL_TABLE;
-
-/* pointers to TL_TABLE with sinwave output offset */
-static INT32 **SIN_TABLE;
-
-/* LFO table */
-static INT32 *AMS_TABLE;
-static INT32 *VIB_TABLE;
-
-/* envelope output curve table */
-/* attack + decay + OFF */
-static INT32 ENV_CURVE[2*EG_ENT+1];
-
-/* multiple table */
-#define ML 2
-static const UINT32 MUL_TABLE[16]= {
-/* 1/2, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15 */
- 0.50*ML, 1.00*ML, 2.00*ML, 3.00*ML, 4.00*ML, 5.00*ML, 6.00*ML, 7.00*ML,
- 8.00*ML, 9.00*ML,10.00*ML,10.00*ML,12.00*ML,12.00*ML,15.00*ML,15.00*ML
-};
-#undef ML
-
-/* dummy attack / decay rate ( when rate == 0 ) */
-static INT32 RATE_0[16]=
-{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
-
-/* -------------------- static state --------------------- */
-
-/* lock level of common table */
-static int num_lock = 0;
-
-/* work table */
-static void *cur_chip = NULL; /* current chip point */
-/* currenct chip state */
-/* static OPLSAMPLE *bufL,*bufR; */
-static OPL_CH *S_CH;
-static OPL_CH *E_CH;
-OPL_SLOT *SLOT7_1,*SLOT7_2,*SLOT8_1,*SLOT8_2;
-
-static INT32 outd[1];
-static INT32 ams;
-static INT32 vib;
-INT32 *ams_table;
-INT32 *vib_table;
-static INT32 amsIncr;
-static INT32 vibIncr;
-static INT32 feedback2; /* connect for SLOT 2 */
-
-/* log output level */
-#define LOG_ERR 3 /* ERROR */
-#define LOG_WAR 2 /* WARNING */
-#define LOG_INF 1 /* INFORMATION */
-
-//#define LOG_LEVEL LOG_INF
-#define LOG_LEVEL LOG_ERR
-
-//#define LOG(n,x) if( (n)>=LOG_LEVEL ) logerror x
-#define LOG(n,x)
-
-/* --------------------- subroutines --------------------- */
-
-INLINE int Limit( int val, int max, int min ) {
- if ( val > max )
- val = max;
- else if ( val < min )
- val = min;
-
- return val;
-}
-
-/* status set and IRQ handling */
-INLINE void OPL_STATUS_SET(FM_OPL *OPL,int flag)
-{
- /* set status flag */
- OPL->status |= flag;
- if(!(OPL->status & 0x80))
- {
- if(OPL->status & OPL->statusmask)
- { /* IRQ on */
- OPL->status |= 0x80;
- /* callback user interrupt handler (IRQ is OFF to ON) */
- if(OPL->IRQHandler) (OPL->IRQHandler)(OPL->IRQParam,1);
- }
- }
-}
-
-/* status reset and IRQ handling */
-INLINE void OPL_STATUS_RESET(FM_OPL *OPL,int flag)
-{
- /* reset status flag */
- OPL->status &=~flag;
- if((OPL->status & 0x80))
- {
- if (!(OPL->status & OPL->statusmask) )
- {
- OPL->status &= 0x7f;
- /* callback user interrupt handler (IRQ is ON to OFF) */
- if(OPL->IRQHandler) (OPL->IRQHandler)(OPL->IRQParam,0);
- }
- }
-}
-
-/* IRQ mask set */
-INLINE void OPL_STATUSMASK_SET(FM_OPL *OPL,int flag)
-{
- OPL->statusmask = flag;
- /* IRQ handling check */
- OPL_STATUS_SET(OPL,0);
- OPL_STATUS_RESET(OPL,0);
-}
-
-/* ----- key on ----- */
-INLINE void OPL_KEYON(OPL_SLOT *SLOT)
-{
- /* sin wave restart */
- SLOT->Cnt = 0;
- /* set attack */
- SLOT->evm = ENV_MOD_AR;
- SLOT->evs = SLOT->evsa;
- SLOT->evc = EG_AST;
- SLOT->eve = EG_AED;
-}
-/* ----- key off ----- */
-INLINE void OPL_KEYOFF(OPL_SLOT *SLOT)
-{
- if( SLOT->evm > ENV_MOD_RR)
- {
- /* set envelope counter from envleope output */
- SLOT->evm = ENV_MOD_RR;
- if( !(SLOT->evc&EG_DST) )
- //SLOT->evc = (ENV_CURVE[SLOT->evc>>ENV_BITS]<<ENV_BITS) + EG_DST;
- SLOT->evc = EG_DST;
- SLOT->eve = EG_DED;
- SLOT->evs = SLOT->evsr;
- }
-}
-
-/* ---------- calcrate Envelope Generator & Phase Generator ---------- */
-/* return : envelope output */
-INLINE UINT32 OPL_CALC_SLOT( OPL_SLOT *SLOT )
-{
- /* calcrate envelope generator */
- if( (SLOT->evc+=SLOT->evs) >= SLOT->eve )
- {
- switch( SLOT->evm ){
- case ENV_MOD_AR: /* ATTACK -> DECAY1 */
- /* next DR */
- SLOT->evm = ENV_MOD_DR;
- SLOT->evc = EG_DST;
- SLOT->eve = SLOT->SL;
- SLOT->evs = SLOT->evsd;
- break;
- case ENV_MOD_DR: /* DECAY -> SL or RR */
- SLOT->evc = SLOT->SL;
- SLOT->eve = EG_DED;
- if(SLOT->eg_typ)
- {
- SLOT->evs = 0;
- }
- else
- {
- SLOT->evm = ENV_MOD_RR;
- SLOT->evs = SLOT->evsr;
- }
- break;
- case ENV_MOD_RR: /* RR -> OFF */
- SLOT->evc = EG_OFF;
- SLOT->eve = EG_OFF+1;
- SLOT->evs = 0;
- break;
- }
- }
- /* calcrate envelope */
- return SLOT->TLL+ENV_CURVE[SLOT->evc>>ENV_BITS]+(SLOT->ams ? ams : 0);
-}
-
-/* set algorythm connection */
-static void set_algorythm( OPL_CH *CH)
-{
- INT32 *carrier = &outd[0];
- CH->connect1 = CH->CON ? carrier : &feedback2;
- CH->connect2 = carrier;
-}
-
-/* ---------- frequency counter for operater update ---------- */
-INLINE void CALC_FCSLOT(OPL_CH *CH,OPL_SLOT *SLOT)
-{
- int ksr;
-
- /* frequency step counter */
- SLOT->Incr = CH->fc * SLOT->mul;
- ksr = CH->kcode >> SLOT->KSR;
-
- if( SLOT->ksr != ksr )
- {
- SLOT->ksr = ksr;
- /* attack , decay rate recalcration */
- SLOT->evsa = SLOT->AR[ksr];
- SLOT->evsd = SLOT->DR[ksr];
- SLOT->evsr = SLOT->RR[ksr];
- }
- SLOT->TLL = SLOT->TL + (CH->ksl_base>>SLOT->ksl);
-}
-
-/* set multi,am,vib,EG-TYP,KSR,mul */
-INLINE void set_mul(FM_OPL *OPL,int slot,int v)
-{
- OPL_CH *CH = &OPL->P_CH[slot/2];
- OPL_SLOT *SLOT = &CH->SLOT[slot&1];
-
- SLOT->mul = MUL_TABLE[v&0x0f];
- SLOT->KSR = (v&0x10) ? 0 : 2;
- SLOT->eg_typ = (v&0x20)>>5;
- SLOT->vib = (v&0x40);
- SLOT->ams = (v&0x80);
- CALC_FCSLOT(CH,SLOT);
-}
-
-/* set ksl & tl */
-INLINE void set_ksl_tl(FM_OPL *OPL,int slot,int v)
-{
- OPL_CH *CH = &OPL->P_CH[slot/2];
- OPL_SLOT *SLOT = &CH->SLOT[slot&1];
- int ksl = v>>6; /* 0 / 1.5 / 3 / 6 db/OCT */
-
- SLOT->ksl = ksl ? 3-ksl : 31;
- SLOT->TL = (v&0x3f)*(0.75/EG_STEP); /* 0.75db step */
-
- if( !(OPL->mode&0x80) )
- { /* not CSM latch total level */
- SLOT->TLL = SLOT->TL + (CH->ksl_base>>SLOT->ksl);
- }
-}
-
-/* set attack rate & decay rate */
-INLINE void set_ar_dr(FM_OPL *OPL,int slot,int v)
-{
- OPL_CH *CH = &OPL->P_CH[slot/2];
- OPL_SLOT *SLOT = &CH->SLOT[slot&1];
- int ar = v>>4;
- int dr = v&0x0f;
-
- SLOT->AR = ar ? &OPL->AR_TABLE[ar<<2] : RATE_0;
- SLOT->evsa = SLOT->AR[SLOT->ksr];
- if( SLOT->evm == ENV_MOD_AR ) SLOT->evs = SLOT->evsa;
-
- SLOT->DR = dr ? &OPL->DR_TABLE[dr<<2] : RATE_0;
- SLOT->evsd = SLOT->DR[SLOT->ksr];
- if( SLOT->evm == ENV_MOD_DR ) SLOT->evs = SLOT->evsd;
-}
-
-/* set sustain level & release rate */
-INLINE void set_sl_rr(FM_OPL *OPL,int slot,int v)
-{
- OPL_CH *CH = &OPL->P_CH[slot/2];
- OPL_SLOT *SLOT = &CH->SLOT[slot&1];
- int sl = v>>4;
- int rr = v & 0x0f;
-
- SLOT->SL = SL_TABLE[sl];
- if( SLOT->evm == ENV_MOD_DR ) SLOT->eve = SLOT->SL;
- SLOT->RR = &OPL->DR_TABLE[rr<<2];
- SLOT->evsr = SLOT->RR[SLOT->ksr];
- if( SLOT->evm == ENV_MOD_RR ) SLOT->evs = SLOT->evsr;
-}
-
-/* operator output calcrator */
-#define OP_OUT(slot,env,con) slot->wavetable[((slot->Cnt+con)/(0x1000000/SIN_ENT))&(SIN_ENT-1)][env]
-/* ---------- calcrate one of channel ---------- */
-INLINE void OPL_CALC_CH( OPL_CH *CH )
-{
- UINT32 env_out;
- OPL_SLOT *SLOT;
-
- feedback2 = 0;
- /* SLOT 1 */
- SLOT = &CH->SLOT[SLOT1];
- env_out=OPL_CALC_SLOT(SLOT);
- if( env_out < EG_ENT-1 )
- {
- /* PG */
- if(SLOT->vib) SLOT->Cnt += (SLOT->Incr*vib/VIB_RATE);
- else SLOT->Cnt += SLOT->Incr;
- /* connectoion */
- if(CH->FB)
- {
- int feedback1 = (CH->op1_out[0]+CH->op1_out[1])>>CH->FB;
- CH->op1_out[1] = CH->op1_out[0];
- *CH->connect1 += CH->op1_out[0] = OP_OUT(SLOT,env_out,feedback1);
- }
- else
- {
- *CH->connect1 += OP_OUT(SLOT,env_out,0);
- }
- }else
- {
- CH->op1_out[1] = CH->op1_out[0];
- CH->op1_out[0] = 0;
- }
- /* SLOT 2 */
- SLOT = &CH->SLOT[SLOT2];
- env_out=OPL_CALC_SLOT(SLOT);
- if( env_out < EG_ENT-1 )
- {
- /* PG */
- if(SLOT->vib) SLOT->Cnt += (SLOT->Incr*vib/VIB_RATE);
- else SLOT->Cnt += SLOT->Incr;
- /* connectoion */
- outd[0] += OP_OUT(SLOT,env_out, feedback2);
- }
-}
-
-/* ---------- calcrate rythm block ---------- */
-#define WHITE_NOISE_db 6.0
-INLINE void OPL_CALC_RH( OPL_CH *CH )
-{
- UINT32 env_tam,env_sd,env_top,env_hh;
- int whitenoise = (rand()&1)*(WHITE_NOISE_db/EG_STEP);
- INT32 tone8;
-
- OPL_SLOT *SLOT;
- int env_out;
-
- /* BD : same as FM serial mode and output level is large */
- feedback2 = 0;
- /* SLOT 1 */
- SLOT = &CH[6].SLOT[SLOT1];
- env_out=OPL_CALC_SLOT(SLOT);
- if( env_out < EG_ENT-1 )
- {
- /* PG */
- if(SLOT->vib) SLOT->Cnt += (SLOT->Incr*vib/VIB_RATE);
- else SLOT->Cnt += SLOT->Incr;
- /* connectoion */
- if(CH[6].FB)
- {
- int feedback1 = (CH[6].op1_out[0]+CH[6].op1_out[1])>>CH[6].FB;
- CH[6].op1_out[1] = CH[6].op1_out[0];
- feedback2 = CH[6].op1_out[0] = OP_OUT(SLOT,env_out,feedback1);
- }
- else
- {
- feedback2 = OP_OUT(SLOT,env_out,0);
- }
- }else
- {
- feedback2 = 0;
- CH[6].op1_out[1] = CH[6].op1_out[0];
- CH[6].op1_out[0] = 0;
- }
- /* SLOT 2 */
- SLOT = &CH[6].SLOT[SLOT2];
- env_out=OPL_CALC_SLOT(SLOT);
- if( env_out < EG_ENT-1 )
- {
- /* PG */
- if(SLOT->vib) SLOT->Cnt += (SLOT->Incr*vib/VIB_RATE);
- else SLOT->Cnt += SLOT->Incr;
- /* connectoion */
- outd[0] += OP_OUT(SLOT,env_out, feedback2)*2;
- }
-
- // SD (17) = mul14[fnum7] + white noise
- // TAM (15) = mul15[fnum8]
- // TOP (18) = fnum6(mul18[fnum8]+whitenoise)
- // HH (14) = fnum7(mul18[fnum8]+whitenoise) + white noise
- env_sd =OPL_CALC_SLOT(SLOT7_2) + whitenoise;
- env_tam=OPL_CALC_SLOT(SLOT8_1);
- env_top=OPL_CALC_SLOT(SLOT8_2);
- env_hh =OPL_CALC_SLOT(SLOT7_1) + whitenoise;
-
- /* PG */
- if(SLOT7_1->vib) SLOT7_1->Cnt += (2*SLOT7_1->Incr*vib/VIB_RATE);
- else SLOT7_1->Cnt += 2*SLOT7_1->Incr;
- if(SLOT7_2->vib) SLOT7_2->Cnt += ((CH[7].fc*8)*vib/VIB_RATE);
- else SLOT7_2->Cnt += (CH[7].fc*8);
- if(SLOT8_1->vib) SLOT8_1->Cnt += (SLOT8_1->Incr*vib/VIB_RATE);
- else SLOT8_1->Cnt += SLOT8_1->Incr;
- if(SLOT8_2->vib) SLOT8_2->Cnt += ((CH[8].fc*48)*vib/VIB_RATE);
- else SLOT8_2->Cnt += (CH[8].fc*48);
-
- tone8 = OP_OUT(SLOT8_2,whitenoise,0 );
-
- /* SD */
- if( env_sd < EG_ENT-1 )
- outd[0] += OP_OUT(SLOT7_1,env_sd, 0)*8;
- /* TAM */
- if( env_tam < EG_ENT-1 )
- outd[0] += OP_OUT(SLOT8_1,env_tam, 0)*2;
- /* TOP-CY */
- if( env_top < EG_ENT-1 )
- outd[0] += OP_OUT(SLOT7_2,env_top,tone8)*2;
- /* HH */
- if( env_hh < EG_ENT-1 )
- outd[0] += OP_OUT(SLOT7_2,env_hh,tone8)*2;
-}
-
-/* ----------- initialize time tabls ----------- */
-static void init_timetables( FM_OPL *OPL , int ARRATE , int DRRATE )
-{
- int i;
- double rate;
-
- /* make attack rate & decay rate tables */
- for (i = 0;i < 4;i++) OPL->AR_TABLE[i] = OPL->DR_TABLE[i] = 0;
- for (i = 4;i <= 60;i++){
- rate = OPL->freqbase; /* frequency rate */
- if( i < 60 ) rate *= 1.0+(i&3)*0.25; /* b0-1 : x1 , x1.25 , x1.5 , x1.75 */
- rate *= 1<<((i>>2)-1); /* b2-5 : shift bit */
- rate *= (double)(EG_ENT<<ENV_BITS);
- OPL->AR_TABLE[i] = rate / ARRATE;
- OPL->DR_TABLE[i] = rate / DRRATE;
- }
- for (i = 60;i < 76;i++)
- {
- OPL->AR_TABLE[i] = EG_AED-1;
- OPL->DR_TABLE[i] = OPL->DR_TABLE[60];
- }
-#if 0
- for (i = 0;i < 64 ;i++){ /* make for overflow area */
- LOG(LOG_WAR,("rate %2d , ar %f ms , dr %f ms \n",i,
- ((double)(EG_ENT<<ENV_BITS) / OPL->AR_TABLE[i]) * (1000.0 / OPL->rate),
- ((double)(EG_ENT<<ENV_BITS) / OPL->DR_TABLE[i]) * (1000.0 / OPL->rate) ));
- }
-#endif
-}
-
-/* ---------- generic table initialize ---------- */
-static int OPLOpenTable( void )
-{
- int s,t;
- double rate;
- int i,j;
- double pom;
-
- /* allocate dynamic tables */
- if( (TL_TABLE = malloc(TL_MAX*2*sizeof(INT32))) == NULL)
- return 0;
- if( (SIN_TABLE = malloc(SIN_ENT*4 *sizeof(INT32 *))) == NULL)
- {
- free(TL_TABLE);
- return 0;
- }
- if( (AMS_TABLE = malloc(AMS_ENT*2 *sizeof(INT32))) == NULL)
- {
- free(TL_TABLE);
- free(SIN_TABLE);
- return 0;
- }
- if( (VIB_TABLE = malloc(VIB_ENT*2 *sizeof(INT32))) == NULL)
- {
- free(TL_TABLE);
- free(SIN_TABLE);
- free(AMS_TABLE);
- return 0;
- }
- /* make total level table */
- for (t = 0;t < EG_ENT-1 ;t++){
- rate = ((1<<TL_BITS)-1)/pow(10,EG_STEP*t/20); /* dB -> voltage */
- TL_TABLE[ t] = (int)rate;
- TL_TABLE[TL_MAX+t] = -TL_TABLE[t];
-/* LOG(LOG_INF,("TotalLevel(%3d) = %x\n",t,TL_TABLE[t]));*/
- }
- /* fill volume off area */
- for ( t = EG_ENT-1; t < TL_MAX ;t++){
- TL_TABLE[t] = TL_TABLE[TL_MAX+t] = 0;
- }
-
- /* make sinwave table (total level offet) */
- /* degree 0 = degree 180 = off */
- SIN_TABLE[0] = SIN_TABLE[SIN_ENT/2] = &TL_TABLE[EG_ENT-1];
- for (s = 1;s <= SIN_ENT/4;s++){
- pom = sin(2*PI*s/SIN_ENT); /* sin */
- pom = 20*log10(1/pom); /* decibel */
- j = pom / EG_STEP; /* TL_TABLE steps */
-
- /* degree 0 - 90 , degree 180 - 90 : plus section */
- SIN_TABLE[ s] = SIN_TABLE[SIN_ENT/2-s] = &TL_TABLE[j];
- /* degree 180 - 270 , degree 360 - 270 : minus section */
- SIN_TABLE[SIN_ENT/2+s] = SIN_TABLE[SIN_ENT -s] = &TL_TABLE[TL_MAX+j];
-/* LOG(LOG_INF,("sin(%3d) = %f:%f db\n",s,pom,(double)j * EG_STEP));*/
- }
- for (s = 0;s < SIN_ENT;s++)
- {
- SIN_TABLE[SIN_ENT*1+s] = s<(SIN_ENT/2) ? SIN_TABLE[s] : &TL_TABLE[EG_ENT];
- SIN_TABLE[SIN_ENT*2+s] = SIN_TABLE[s % (SIN_ENT/2)];
- SIN_TABLE[SIN_ENT*3+s] = (s/(SIN_ENT/4))&1 ? &TL_TABLE[EG_ENT] : SIN_TABLE[SIN_ENT*2+s];
- }
-
- /* envelope counter -> envelope output table */
- for (i=0; i<EG_ENT; i++)
- {
- /* ATTACK curve */
- pom = pow( ((double)(EG_ENT-1-i)/EG_ENT) , 8 ) * EG_ENT;
- /* if( pom >= EG_ENT ) pom = EG_ENT-1; */
- ENV_CURVE[i] = (int)pom;
- /* DECAY ,RELEASE curve */
- ENV_CURVE[(EG_DST>>ENV_BITS)+i]= i;
- }
- /* off */
- ENV_CURVE[EG_OFF>>ENV_BITS]= EG_ENT-1;
- /* make LFO ams table */
- for (i=0; i<AMS_ENT; i++)
- {
- pom = (1.0+sin(2*PI*i/AMS_ENT))/2; /* sin */
- AMS_TABLE[i] = (1.0/EG_STEP)*pom; /* 1dB */
- AMS_TABLE[AMS_ENT+i] = (4.8/EG_STEP)*pom; /* 4.8dB */
- }
- /* make LFO vibrate table */
- for (i=0; i<VIB_ENT; i++)
- {
- /* 100cent = 1seminote = 6% ?? */
- pom = (double)VIB_RATE*0.06*sin(2*PI*i/VIB_ENT); /* +-100sect step */
- VIB_TABLE[i] = VIB_RATE + (pom*0.07); /* +- 7cent */
- VIB_TABLE[VIB_ENT+i] = VIB_RATE + (pom*0.14); /* +-14cent */
- /* LOG(LOG_INF,("vib %d=%d\n",i,VIB_TABLE[VIB_ENT+i])); */
- }
- return 1;
-}
-
-
-static void OPLCloseTable( void )
-{
- free(TL_TABLE);
- free(SIN_TABLE);
- free(AMS_TABLE);
- free(VIB_TABLE);
-}
-
-/* CSM Key Controll */
-INLINE void CSMKeyControll(OPL_CH *CH)
-{
- OPL_SLOT *slot1 = &CH->SLOT[SLOT1];
- OPL_SLOT *slot2 = &CH->SLOT[SLOT2];
- /* all key off */
- OPL_KEYOFF(slot1);
- OPL_KEYOFF(slot2);
- /* total level latch */
- slot1->TLL = slot1->TL + (CH->ksl_base>>slot1->ksl);
- slot1->TLL = slot1->TL + (CH->ksl_base>>slot1->ksl);
- /* key on */
- CH->op1_out[0] = CH->op1_out[1] = 0;
- OPL_KEYON(slot1);
- OPL_KEYON(slot2);
-}
-
-/* ---------- opl initialize ---------- */
-static void OPL_initalize(FM_OPL *OPL)
-{
- int fn;
-
- /* frequency base */
- OPL->freqbase = (OPL->rate) ? ((double)OPL->clock / OPL->rate) / 72 : 0;
- /* Timer base time */
- OPL->TimerBase = 1.0/((double)OPL->clock / 72.0 );
- /* make time tables */
- init_timetables( OPL , OPL_ARRATE , OPL_DRRATE );
- /* make fnumber -> increment counter table */
- for( fn=0 ; fn < 1024 ; fn++ )
- {
- OPL->FN_TABLE[fn] = OPL->freqbase * fn * FREQ_RATE * (1<<7) / 2;
- }
- /* LFO freq.table */
- OPL->amsIncr = OPL->rate ? (double)AMS_ENT*(1<<AMS_SHIFT) / OPL->rate * 3.7 * ((double)OPL->clock/3600000) : 0;
- OPL->vibIncr = OPL->rate ? (double)VIB_ENT*(1<<VIB_SHIFT) / OPL->rate * 6.4 * ((double)OPL->clock/3600000) : 0;
-}
-
-/* ---------- write a OPL registers ---------- */
-static void OPLWriteReg(FM_OPL *OPL, int r, int v)
-{
- OPL_CH *CH;
- int slot;
- int block_fnum;
-
- switch(r&0xe0)
- {
- case 0x00: /* 00-1f:controll */
- switch(r&0x1f)
- {
- case 0x01:
- /* wave selector enable */
- if(OPL->type&OPL_TYPE_WAVESEL)
- {
- OPL->wavesel = v&0x20;
- if(!OPL->wavesel)
- {
- /* preset compatible mode */
- int c;
- for(c=0;c<OPL->max_ch;c++)
- {
- OPL->P_CH[c].SLOT[SLOT1].wavetable = &SIN_TABLE[0];
- OPL->P_CH[c].SLOT[SLOT2].wavetable = &SIN_TABLE[0];
- }
- }
- }
- return;
- case 0x02: /* Timer 1 */
- OPL->T[0] = (256-v)*4;
- break;
- case 0x03: /* Timer 2 */
- OPL->T[1] = (256-v)*16;
- return;
- case 0x04: /* IRQ clear / mask and Timer enable */
- if(v&0x80)
- { /* IRQ flag clear */
- OPL_STATUS_RESET(OPL,0x7f);
- }
- else
- { /* set IRQ mask ,timer enable*/
- UINT8 st1 = v&1;
- UINT8 st2 = (v>>1)&1;
- /* IRQRST,T1MSK,t2MSK,EOSMSK,BRMSK,x,ST2,ST1 */
- OPL_STATUS_RESET(OPL,v&0x78);
- OPL_STATUSMASK_SET(OPL,((~v)&0x78)|0x01);
- /* timer 2 */
- if(OPL->st[1] != st2)
- {
- double interval = st2 ? (double)OPL->T[1]*OPL->TimerBase : 0.0;
- OPL->st[1] = st2;
- if (OPL->TimerHandler) (OPL->TimerHandler)(OPL->TimerParam+1,interval);
- }
- /* timer 1 */
- if(OPL->st[0] != st1)
- {
- double interval = st1 ? (double)OPL->T[0]*OPL->TimerBase : 0.0;
- OPL->st[0] = st1;
- if (OPL->TimerHandler) (OPL->TimerHandler)(OPL->TimerParam+0,interval);
- }
- }
- return;
-#if BUILD_Y8950
- case 0x06: /* Key Board OUT */
- if(OPL->type&OPL_TYPE_KEYBOARD)
- {
- if(OPL->keyboardhandler_w)
- OPL->keyboardhandler_w(OPL->keyboard_param,v);
- else
- LOG(LOG_WAR,("OPL:write unmapped KEYBOARD port\n"));
- }
- return;
- case 0x07: /* DELTA-T controll : START,REC,MEMDATA,REPT,SPOFF,x,x,RST */
- if(OPL->type&OPL_TYPE_ADPCM)
- YM_DELTAT_ADPCM_Write(OPL->deltat,r-0x07,v);
- return;
- case 0x08: /* MODE,DELTA-T : CSM,NOTESEL,x,x,smpl,da/ad,64k,rom */
- OPL->mode = v;
- v&=0x1f; /* for DELTA-T unit */
- case 0x09: /* START ADD */
- case 0x0a:
- case 0x0b: /* STOP ADD */
- case 0x0c:
- case 0x0d: /* PRESCALE */
- case 0x0e:
- case 0x0f: /* ADPCM data */
- case 0x10: /* DELTA-N */
- case 0x11: /* DELTA-N */
- case 0x12: /* EG-CTRL */
- if(OPL->type&OPL_TYPE_ADPCM)
- YM_DELTAT_ADPCM_Write(OPL->deltat,r-0x07,v);
- return;
-#if 0
- case 0x15: /* DAC data */
- case 0x16:
- case 0x17: /* SHIFT */
- return;
- case 0x18: /* I/O CTRL (Direction) */
- if(OPL->type&OPL_TYPE_IO)
- OPL->portDirection = v&0x0f;
- return;
- case 0x19: /* I/O DATA */
- if(OPL->type&OPL_TYPE_IO)
- {
- OPL->portLatch = v;
- if(OPL->porthandler_w)
- OPL->porthandler_w(OPL->port_param,v&OPL->portDirection);
- }
- return;
- case 0x1a: /* PCM data */
- return;
-#endif
-#endif
- }
- break;
- case 0x20: /* am,vib,ksr,eg type,mul */
- slot = slot_array[r&0x1f];
- if(slot == -1) return;
- set_mul(OPL,slot,v);
- return;
- case 0x40:
- slot = slot_array[r&0x1f];
- if(slot == -1) return;
- set_ksl_tl(OPL,slot,v);
- return;
- case 0x60:
- slot = slot_array[r&0x1f];
- if(slot == -1) return;
- set_ar_dr(OPL,slot,v);
- return;
- case 0x80:
- slot = slot_array[r&0x1f];
- if(slot == -1) return;
- set_sl_rr(OPL,slot,v);
- return;
- case 0xa0:
- switch(r)
- {
- case 0xbd:
- /* amsep,vibdep,r,bd,sd,tom,tc,hh */
- {
- UINT8 rkey = OPL->rythm^v;
- OPL->ams_table = &AMS_TABLE[v&0x80 ? AMS_ENT : 0];
- OPL->vib_table = &VIB_TABLE[v&0x40 ? VIB_ENT : 0];
- OPL->rythm = v&0x3f;
- if(OPL->rythm&0x20)
- {
-#if 0
- usrintf_showmessage("OPL Rythm mode select");
-#endif
- /* BD key on/off */
- if(rkey&0x10)
- {
- if(v&0x10)
- {
- OPL->P_CH[6].op1_out[0] = OPL->P_CH[6].op1_out[1] = 0;
- OPL_KEYON(&OPL->P_CH[6].SLOT[SLOT1]);
- OPL_KEYON(&OPL->P_CH[6].SLOT[SLOT2]);
- }
- else
- {
- OPL_KEYOFF(&OPL->P_CH[6].SLOT[SLOT1]);
- OPL_KEYOFF(&OPL->P_CH[6].SLOT[SLOT2]);
- }
- }
- /* SD key on/off */
- if(rkey&0x08)
- {
- if(v&0x08) OPL_KEYON(&OPL->P_CH[7].SLOT[SLOT2]);
- else OPL_KEYOFF(&OPL->P_CH[7].SLOT[SLOT2]);
- }/* TAM key on/off */
- if(rkey&0x04)
- {
- if(v&0x04) OPL_KEYON(&OPL->P_CH[8].SLOT[SLOT1]);
- else OPL_KEYOFF(&OPL->P_CH[8].SLOT[SLOT1]);
- }
- /* TOP-CY key on/off */
- if(rkey&0x02)
- {
- if(v&0x02) OPL_KEYON(&OPL->P_CH[8].SLOT[SLOT2]);
- else OPL_KEYOFF(&OPL->P_CH[8].SLOT[SLOT2]);
- }
- /* HH key on/off */
- if(rkey&0x01)
- {
- if(v&0x01) OPL_KEYON(&OPL->P_CH[7].SLOT[SLOT1]);
- else OPL_KEYOFF(&OPL->P_CH[7].SLOT[SLOT1]);
- }
- }
- }
- return;
- }
- /* keyon,block,fnum */
- if( (r&0x0f) > 8) return;
- CH = &OPL->P_CH[r&0x0f];
- if(!(r&0x10))
- { /* a0-a8 */
- block_fnum = (CH->block_fnum&0x1f00) | v;
- }
- else
- { /* b0-b8 */
- int keyon = (v>>5)&1;
- block_fnum = ((v&0x1f)<<8) | (CH->block_fnum&0xff);
- if(CH->keyon != keyon)
- {
- if( (CH->keyon=keyon) )
- {
- CH->op1_out[0] = CH->op1_out[1] = 0;
- OPL_KEYON(&CH->SLOT[SLOT1]);
- OPL_KEYON(&CH->SLOT[SLOT2]);
- }
- else
- {
- OPL_KEYOFF(&CH->SLOT[SLOT1]);
- OPL_KEYOFF(&CH->SLOT[SLOT2]);
- }
- }
- }
- /* update */
- if(CH->block_fnum != block_fnum)
- {
- int blockRv = 7-(block_fnum>>10);
- int fnum = block_fnum&0x3ff;
- CH->block_fnum = block_fnum;
-
- CH->ksl_base = KSL_TABLE[block_fnum>>6];
- CH->fc = OPL->FN_TABLE[fnum]>>blockRv;
- CH->kcode = CH->block_fnum>>9;
- if( (OPL->mode&0x40) && CH->block_fnum&0x100) CH->kcode |=1;
- CALC_FCSLOT(CH,&CH->SLOT[SLOT1]);
- CALC_FCSLOT(CH,&CH->SLOT[SLOT2]);
- }
- return;
- case 0xc0:
- /* FB,C */
- if( (r&0x0f) > 8) return;
- CH = &OPL->P_CH[r&0x0f];
- {
- int feedback = (v>>1)&7;
- CH->FB = feedback ? (8+1) - feedback : 0;
- CH->CON = v&1;
- set_algorythm(CH);
- }
- return;
- case 0xe0: /* wave type */
- slot = slot_array[r&0x1f];
- if(slot == -1) return;
- CH = &OPL->P_CH[slot/2];
- if(OPL->wavesel)
- {
- /* LOG(LOG_INF,("OPL SLOT %d wave select %d\n",slot,v&3)); */
- CH->SLOT[slot&1].wavetable = &SIN_TABLE[(v&0x03)*SIN_ENT];
- }
- return;
- }
-}
-
-/* lock/unlock for common table */
-static int OPL_LockTable(void)
-{
- num_lock++;
- if(num_lock>1) return 0;
- /* first time */
- cur_chip = NULL;
- /* allocate total level table (128kb space) */
- if( !OPLOpenTable() )
- {
- num_lock--;
- return -1;
- }
- return 0;
-}
-
-static void OPL_UnLockTable(void)
-{
- if(num_lock) num_lock--;
- if(num_lock) return;
- /* last time */
- cur_chip = NULL;
- OPLCloseTable();
-}
-
-#if (BUILD_YM3812 || BUILD_YM3526)
-/*******************************************************************************/
-/* YM3812 local section */
-/*******************************************************************************/
-
-/* ---------- update one of chip ----------- */
-void YM3812UpdateOne(FM_OPL *OPL, INT16 *buffer, int length)
-{
- int i;
- int data;
- OPLSAMPLE *buf = buffer;
- UINT32 amsCnt = OPL->amsCnt;
- UINT32 vibCnt = OPL->vibCnt;
- UINT8 rythm = OPL->rythm&0x20;
- OPL_CH *CH,*R_CH;
-
- if( (void *)OPL != cur_chip ){
- cur_chip = (void *)OPL;
- /* channel pointers */
- S_CH = OPL->P_CH;
- E_CH = &S_CH[9];
- /* rythm slot */
- SLOT7_1 = &S_CH[7].SLOT[SLOT1];
- SLOT7_2 = &S_CH[7].SLOT[SLOT2];
- SLOT8_1 = &S_CH[8].SLOT[SLOT1];
- SLOT8_2 = &S_CH[8].SLOT[SLOT2];
- /* LFO state */
- amsIncr = OPL->amsIncr;
- vibIncr = OPL->vibIncr;
- ams_table = OPL->ams_table;
- vib_table = OPL->vib_table;
- }
- R_CH = rythm ? &S_CH[6] : E_CH;
- for( i=0; i < length ; i++ )
- {
- /* channel A channel B channel C */
- /* LFO */
- ams = ams_table[(amsCnt+=amsIncr)>>AMS_SHIFT];
- vib = vib_table[(vibCnt+=vibIncr)>>VIB_SHIFT];
- outd[0] = 0;
- /* FM part */
- for(CH=S_CH ; CH < R_CH ; CH++)
- OPL_CALC_CH(CH);
- /* Rythn part */
- if(rythm)
- OPL_CALC_RH(S_CH);
- /* limit check */
- data = Limit( outd[0] , OPL_MAXOUT, OPL_MINOUT );
- /* store to sound buffer */
- buf[i] = data >> OPL_OUTSB;
- }
-
- OPL->amsCnt = amsCnt;
- OPL->vibCnt = vibCnt;
-#ifdef OPL_OUTPUT_LOG
- if(opl_dbg_fp)
- {
- for(opl_dbg_chip=0;opl_dbg_chip<opl_dbg_maxchip;opl_dbg_chip++)
- if( opl_dbg_opl[opl_dbg_chip] == OPL) break;
- fprintf(opl_dbg_fp,"%c%c%c",0x20+opl_dbg_chip,length&0xff,length/256);
- }
-#endif
-}
-#endif /* (BUILD_YM3812 || BUILD_YM3526) */
-
-#if BUILD_Y8950
-
-void Y8950UpdateOne(FM_OPL *OPL, INT16 *buffer, int length)
-{
- int i;
- int data;
- OPLSAMPLE *buf = buffer;
- UINT32 amsCnt = OPL->amsCnt;
- UINT32 vibCnt = OPL->vibCnt;
- UINT8 rythm = OPL->rythm&0x20;
- OPL_CH *CH,*R_CH;
- YM_DELTAT *DELTAT = OPL->deltat;
-
- /* setup DELTA-T unit */
- YM_DELTAT_DECODE_PRESET(DELTAT);
-
- if( (void *)OPL != cur_chip ){
- cur_chip = (void *)OPL;
- /* channel pointers */
- S_CH = OPL->P_CH;
- E_CH = &S_CH[9];
- /* rythm slot */
- SLOT7_1 = &S_CH[7].SLOT[SLOT1];
- SLOT7_2 = &S_CH[7].SLOT[SLOT2];
- SLOT8_1 = &S_CH[8].SLOT[SLOT1];
- SLOT8_2 = &S_CH[8].SLOT[SLOT2];
- /* LFO state */
- amsIncr = OPL->amsIncr;
- vibIncr = OPL->vibIncr;
- ams_table = OPL->ams_table;
- vib_table = OPL->vib_table;
- }
- R_CH = rythm ? &S_CH[6] : E_CH;
- for( i=0; i < length ; i++ )
- {
- /* channel A channel B channel C */
- /* LFO */
- ams = ams_table[(amsCnt+=amsIncr)>>AMS_SHIFT];
- vib = vib_table[(vibCnt+=vibIncr)>>VIB_SHIFT];
- outd[0] = 0;
- /* deltaT ADPCM */
- if( DELTAT->portstate )
- YM_DELTAT_ADPCM_CALC(DELTAT);
- /* FM part */
- for(CH=S_CH ; CH < R_CH ; CH++)
- OPL_CALC_CH(CH);
- /* Rythn part */
- if(rythm)
- OPL_CALC_RH(S_CH);
- /* limit check */
- data = Limit( outd[0] , OPL_MAXOUT, OPL_MINOUT );
- /* store to sound buffer */
- buf[i] = data >> OPL_OUTSB;
- }
- OPL->amsCnt = amsCnt;
- OPL->vibCnt = vibCnt;
- /* deltaT START flag */
- if( !DELTAT->portstate )
- OPL->status &= 0xfe;
-}
-#endif
-
-/* ---------- reset one of chip ---------- */
-void OPLResetChip(FM_OPL *OPL)
-{
- int c,s;
- int i;
-
- /* reset chip */
- OPL->mode = 0; /* normal mode */
- OPL_STATUS_RESET(OPL,0x7f);
- /* reset with register write */
- OPLWriteReg(OPL,0x01,0); /* wabesel disable */
- OPLWriteReg(OPL,0x02,0); /* Timer1 */
- OPLWriteReg(OPL,0x03,0); /* Timer2 */
- OPLWriteReg(OPL,0x04,0); /* IRQ mask clear */
- for(i = 0xff ; i >= 0x20 ; i-- ) OPLWriteReg(OPL,i,0);
- /* reset OPerator paramater */
- for( c = 0 ; c < OPL->max_ch ; c++ )
- {
- OPL_CH *CH = &OPL->P_CH[c];
- /* OPL->P_CH[c].PAN = OPN_CENTER; */
- for(s = 0 ; s < 2 ; s++ )
- {
- /* wave table */
- CH->SLOT[s].wavetable = &SIN_TABLE[0];
- /* CH->SLOT[s].evm = ENV_MOD_RR; */
- CH->SLOT[s].evc = EG_OFF;
- CH->SLOT[s].eve = EG_OFF+1;
- CH->SLOT[s].evs = 0;
- }
- }
-#if BUILD_Y8950
- if(OPL->type&OPL_TYPE_ADPCM)
- {
- YM_DELTAT *DELTAT = OPL->deltat;
-
- DELTAT->freqbase = OPL->freqbase;
- DELTAT->output_pointer = outd;
- DELTAT->portshift = 5;
- DELTAT->output_range = DELTAT_MIXING_LEVEL<<TL_BITS;
- YM_DELTAT_ADPCM_Reset(DELTAT,0);
- }
-#endif
-}
-
-/* ---------- Create one of vietual YM3812 ---------- */
-/* 'rate' is sampling rate and 'bufsiz' is the size of the */
-FM_OPL *OPLCreate(int type, int clock, int rate)
-{
- char *ptr;
- FM_OPL *OPL;
- int state_size;
- int max_ch = 9; /* normaly 9 channels */
-
- if( OPL_LockTable() ==-1) return NULL;
- /* allocate OPL state space */
- state_size = sizeof(FM_OPL);
- state_size += sizeof(OPL_CH)*max_ch;
-#if BUILD_Y8950
- if(type&OPL_TYPE_ADPCM) state_size+= sizeof(YM_DELTAT);
-#endif
- /* allocate memory block */
- ptr = malloc(state_size);
- if(ptr==NULL) return NULL;
- /* clear */
- memset(ptr,0,state_size);
- OPL = (FM_OPL *)ptr; ptr+=sizeof(FM_OPL);
- OPL->P_CH = (OPL_CH *)ptr; ptr+=sizeof(OPL_CH)*max_ch;
-#if BUILD_Y8950
- if(type&OPL_TYPE_ADPCM) OPL->deltat = (YM_DELTAT *)ptr; ptr+=sizeof(YM_DELTAT);
-#endif
- /* set channel state pointer */
- OPL->type = type;
- OPL->clock = clock;
- OPL->rate = rate;
- OPL->max_ch = max_ch;
- /* init grobal tables */
- OPL_initalize(OPL);
- /* reset chip */
- OPLResetChip(OPL);
-#ifdef OPL_OUTPUT_LOG
- if(!opl_dbg_fp)
- {
- opl_dbg_fp = fopen("opllog.opl","wb");
- opl_dbg_maxchip = 0;
- }
- if(opl_dbg_fp)
- {
- opl_dbg_opl[opl_dbg_maxchip] = OPL;
- fprintf(opl_dbg_fp,"%c%c%c%c%c%c",0x00+opl_dbg_maxchip,
- type,
- clock&0xff,
- (clock/0x100)&0xff,
- (clock/0x10000)&0xff,
- (clock/0x1000000)&0xff);
- opl_dbg_maxchip++;
- }
-#endif
- return OPL;
-}
-
-/* ---------- Destroy one of vietual YM3812 ---------- */
-void OPLDestroy(FM_OPL *OPL)
-{
-#ifdef OPL_OUTPUT_LOG
- if(opl_dbg_fp)
- {
- fclose(opl_dbg_fp);
- opl_dbg_fp = NULL;
- }
-#endif
- OPL_UnLockTable();
- free(OPL);
-}
-
-/* ---------- Option handlers ---------- */
-
-void OPLSetTimerHandler(FM_OPL *OPL,OPL_TIMERHANDLER TimerHandler,int channelOffset)
-{
- OPL->TimerHandler = TimerHandler;
- OPL->TimerParam = channelOffset;
-}
-void OPLSetIRQHandler(FM_OPL *OPL,OPL_IRQHANDLER IRQHandler,int param)
-{
- OPL->IRQHandler = IRQHandler;
- OPL->IRQParam = param;
-}
-void OPLSetUpdateHandler(FM_OPL *OPL,OPL_UPDATEHANDLER UpdateHandler,int param)
-{
- OPL->UpdateHandler = UpdateHandler;
- OPL->UpdateParam = param;
-}
-#if BUILD_Y8950
-void OPLSetPortHandler(FM_OPL *OPL,OPL_PORTHANDLER_W PortHandler_w,OPL_PORTHANDLER_R PortHandler_r,int param)
-{
- OPL->porthandler_w = PortHandler_w;
- OPL->porthandler_r = PortHandler_r;
- OPL->port_param = param;
-}
-
-void OPLSetKeyboardHandler(FM_OPL *OPL,OPL_PORTHANDLER_W KeyboardHandler_w,OPL_PORTHANDLER_R KeyboardHandler_r,int param)
-{
- OPL->keyboardhandler_w = KeyboardHandler_w;
- OPL->keyboardhandler_r = KeyboardHandler_r;
- OPL->keyboard_param = param;
-}
-#endif
-/* ---------- YM3812 I/O interface ---------- */
-int OPLWrite(FM_OPL *OPL,int a,int v)
-{
- if( !(a&1) )
- { /* address port */
- OPL->address = v & 0xff;
- }
- else
- { /* data port */
- if(OPL->UpdateHandler) OPL->UpdateHandler(OPL->UpdateParam,0);
-#ifdef OPL_OUTPUT_LOG
- if(opl_dbg_fp)
- {
- for(opl_dbg_chip=0;opl_dbg_chip<opl_dbg_maxchip;opl_dbg_chip++)
- if( opl_dbg_opl[opl_dbg_chip] == OPL) break;
- fprintf(opl_dbg_fp,"%c%c%c",0x10+opl_dbg_chip,OPL->address,v);
- }
-#endif
- OPLWriteReg(OPL,OPL->address,v);
- }
- return OPL->status>>7;
-}
-
-unsigned char OPLRead(FM_OPL *OPL,int a)
-{
- if( !(a&1) )
- { /* status port */
- return OPL->status & (OPL->statusmask|0x80);
- }
- /* data port */
- switch(OPL->address)
- {
- case 0x05: /* KeyBoard IN */
- if(OPL->type&OPL_TYPE_KEYBOARD)
- {
- if(OPL->keyboardhandler_r)
- return OPL->keyboardhandler_r(OPL->keyboard_param);
- else
- LOG(LOG_WAR,("OPL:read unmapped KEYBOARD port\n"));
- }
- return 0;
-#if 0
- case 0x0f: /* ADPCM-DATA */
- return 0;
-#endif
- case 0x19: /* I/O DATA */
- if(OPL->type&OPL_TYPE_IO)
- {
- if(OPL->porthandler_r)
- return OPL->porthandler_r(OPL->port_param);
- else
- LOG(LOG_WAR,("OPL:read unmapped I/O port\n"));
- }
- return 0;
- case 0x1a: /* PCM-DATA */
- return 0;
- }
- return 0;
-}
-
-int OPLTimerOver(FM_OPL *OPL,int c)
-{
- if( c )
- { /* Timer B */
- OPL_STATUS_SET(OPL,0x20);
- }
- else
- { /* Timer A */
- OPL_STATUS_SET(OPL,0x40);
- /* CSM mode key,TL controll */
- if( OPL->mode & 0x80 )
- { /* CSM mode total level latch and auto key on */
- int ch;
- if(OPL->UpdateHandler) OPL->UpdateHandler(OPL->UpdateParam,0);
- for(ch=0;ch<9;ch++)
- CSMKeyControll( &OPL->P_CH[ch] );
- }
- }
- /* reload timer */
- if (OPL->TimerHandler) (OPL->TimerHandler)(OPL->TimerParam+c,(double)OPL->T[c]*OPL->TimerBase);
- return OPL->status>>7;
-}
+++ /dev/null
-#ifndef __FMOPL_H_
-#define __FMOPL_H_
-
-/* --- select emulation chips --- */
-#define BUILD_YM3812 (HAS_YM3812)
-//#define BUILD_YM3526 (HAS_YM3526)
-//#define BUILD_Y8950 (HAS_Y8950)
-
-/* --- system optimize --- */
-/* select bit size of output : 8 or 16 */
-#define OPL_OUTPUT_BIT 16
-
-/* compiler dependence */
-#ifndef OSD_CPU_H
-#define OSD_CPU_H
-typedef unsigned char UINT8; /* unsigned 8bit */
-typedef unsigned short UINT16; /* unsigned 16bit */
-typedef unsigned int UINT32; /* unsigned 32bit */
-typedef signed char INT8; /* signed 8bit */
-typedef signed short INT16; /* signed 16bit */
-typedef signed int INT32; /* signed 32bit */
-#endif
-
-#if (OPL_OUTPUT_BIT==16)
-typedef INT16 OPLSAMPLE;
-#endif
-#if (OPL_OUTPUT_BIT==8)
-typedef unsigned char OPLSAMPLE;
-#endif
-
-
-#if BUILD_Y8950
-#include "ymdeltat.h"
-#endif
-
-typedef void (*OPL_TIMERHANDLER)(int channel,double interval_Sec);
-typedef void (*OPL_IRQHANDLER)(int param,int irq);
-typedef void (*OPL_UPDATEHANDLER)(int param,int min_interval_us);
-typedef void (*OPL_PORTHANDLER_W)(int param,unsigned char data);
-typedef unsigned char (*OPL_PORTHANDLER_R)(int param);
-
-/* !!!!! here is private section , do not access there member direct !!!!! */
-
-#define OPL_TYPE_WAVESEL 0x01 /* waveform select */
-#define OPL_TYPE_ADPCM 0x02 /* DELTA-T ADPCM unit */
-#define OPL_TYPE_KEYBOARD 0x04 /* keyboard interface */
-#define OPL_TYPE_IO 0x08 /* I/O port */
-
-/* Saving is necessary for member of the 'R' mark for suspend/resume */
-/* ---------- OPL one of slot ---------- */
-typedef struct fm_opl_slot {
- INT32 TL; /* total level :TL << 8 */
- INT32 TLL; /* adjusted now TL */
- UINT8 KSR; /* key scale rate :(shift down bit) */
- INT32 *AR; /* attack rate :&AR_TABLE[AR<<2] */
- INT32 *DR; /* decay rate :&DR_TALBE[DR<<2] */
- INT32 SL; /* sustin level :SL_TALBE[SL] */
- INT32 *RR; /* release rate :&DR_TABLE[RR<<2] */
- UINT8 ksl; /* keyscale level :(shift down bits) */
- UINT8 ksr; /* key scale rate :kcode>>KSR */
- UINT32 mul; /* multiple :ML_TABLE[ML] */
- UINT32 Cnt; /* frequency count : */
- UINT32 Incr; /* frequency step : */
- /* envelope generator state */
- UINT8 eg_typ; /* envelope type flag */
- UINT8 evm; /* envelope phase */
- INT32 evc; /* envelope counter */
- INT32 eve; /* envelope counter end point */
- INT32 evs; /* envelope counter step */
- INT32 evsa; /* envelope step for AR :AR[ksr] */
- INT32 evsd; /* envelope step for DR :DR[ksr] */
- INT32 evsr; /* envelope step for RR :RR[ksr] */
- /* LFO */
- UINT8 ams; /* ams flag */
- UINT8 vib; /* vibrate flag */
- /* wave selector */
- INT32 **wavetable;
-}OPL_SLOT;
-
-/* ---------- OPL one of channel ---------- */
-typedef struct fm_opl_channel {
- OPL_SLOT SLOT[2];
- UINT8 CON; /* connection type */
- UINT8 FB; /* feed back :(shift down bit) */
- INT32 *connect1; /* slot1 output pointer */
- INT32 *connect2; /* slot2 output pointer */
- INT32 op1_out[2]; /* slot1 output for selfeedback */
- /* phase generator state */
- UINT32 block_fnum; /* block+fnum : */
- UINT8 kcode; /* key code : KeyScaleCode */
- UINT32 fc; /* Freq. Increment base */
- UINT32 ksl_base; /* KeyScaleLevel Base step */
- UINT8 keyon; /* key on/off flag */
-} OPL_CH;
-
-/* OPL state */
-typedef struct fm_opl_f {
- UINT8 type; /* chip type */
- int clock; /* master clock (Hz) */
- int rate; /* sampling rate (Hz) */
- double freqbase; /* frequency base */
- double TimerBase; /* Timer base time (==sampling time) */
- UINT8 address; /* address register */
- UINT8 status; /* status flag */
- UINT8 statusmask; /* status mask */
- UINT32 mode; /* Reg.08 : CSM , notesel,etc. */
- /* Timer */
- int T[2]; /* timer counter */
- UINT8 st[2]; /* timer enable */
- /* FM channel slots */
- OPL_CH *P_CH; /* pointer of CH */
- int max_ch; /* maximum channel */
- /* Rythm sention */
- UINT8 rythm; /* Rythm mode , key flag */
-#if BUILD_Y8950
- /* Delta-T ADPCM unit (Y8950) */
- YM_DELTAT *deltat; /* DELTA-T ADPCM */
-#endif
- /* Keyboard / I/O interface unit (Y8950) */
- UINT8 portDirection;
- UINT8 portLatch;
- OPL_PORTHANDLER_R porthandler_r;
- OPL_PORTHANDLER_W porthandler_w;
- int port_param;
- OPL_PORTHANDLER_R keyboardhandler_r;
- OPL_PORTHANDLER_W keyboardhandler_w;
- int keyboard_param;
- /* time tables */
- INT32 AR_TABLE[75]; /* atttack rate tables */
- INT32 DR_TABLE[75]; /* decay rate tables */
- UINT32 FN_TABLE[1024]; /* fnumber -> increment counter */
- /* LFO */
- INT32 *ams_table;
- INT32 *vib_table;
- INT32 amsCnt;
- INT32 amsIncr;
- INT32 vibCnt;
- INT32 vibIncr;
- /* wave selector enable flag */
- UINT8 wavesel;
- /* external event callback handler */
- OPL_TIMERHANDLER TimerHandler; /* TIMER handler */
- int TimerParam; /* TIMER parameter */
- OPL_IRQHANDLER IRQHandler; /* IRQ handler */
- int IRQParam; /* IRQ parameter */
- OPL_UPDATEHANDLER UpdateHandler; /* stream update handler */
- int UpdateParam; /* stream update parameter */
-} FM_OPL;
-
-/* ---------- Generic interface section ---------- */
-#define OPL_TYPE_YM3526 (0)
-#define OPL_TYPE_YM3812 (OPL_TYPE_WAVESEL)
-#define OPL_TYPE_Y8950 (OPL_TYPE_ADPCM|OPL_TYPE_KEYBOARD|OPL_TYPE_IO)
-
-FM_OPL *OPLCreate(int type, int clock, int rate);
-void OPLDestroy(FM_OPL *OPL);
-void OPLSetTimerHandler(FM_OPL *OPL,OPL_TIMERHANDLER TimerHandler,int channelOffset);
-void OPLSetIRQHandler(FM_OPL *OPL,OPL_IRQHANDLER IRQHandler,int param);
-void OPLSetUpdateHandler(FM_OPL *OPL,OPL_UPDATEHANDLER UpdateHandler,int param);
-/* Y8950 port handlers */
-void OPLSetPortHandler(FM_OPL *OPL,OPL_PORTHANDLER_W PortHandler_w,OPL_PORTHANDLER_R PortHandler_r,int param);
-void OPLSetKeyboardHandler(FM_OPL *OPL,OPL_PORTHANDLER_W KeyboardHandler_w,OPL_PORTHANDLER_R KeyboardHandler_r,int param);
-
-void OPLResetChip(FM_OPL *OPL);
-int OPLWrite(FM_OPL *OPL,int a,int v);
-unsigned char OPLRead(FM_OPL *OPL,int a);
-int OPLTimerOver(FM_OPL *OPL,int c);
-
-/* YM3626/YM3812 local section */
-void YM3812UpdateOne(FM_OPL *OPL, INT16 *buffer, int length);
-
-void Y8950UpdateOne(FM_OPL *OPL, INT16 *buffer, int length);
-
-#endif
+++ /dev/null
-/*
- * QEMU 8253/8254 interval timer emulation
- *
- * Copyright (c) 2003-2004 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "vl.h"
-#include <xenctrl.h>
-#include <xen/hvm/ioreq.h>
-
-//#define DEBUG_PIT
-
-#define RW_STATE_LSB 1
-#define RW_STATE_MSB 2
-#define RW_STATE_WORD0 3
-#define RW_STATE_WORD1 4
-
-typedef struct PITChannelState {
- int count; /* can be 65536 */
- uint16_t latched_count;
- uint8_t count_latched;
- uint8_t status_latched;
- uint8_t status;
- uint8_t read_state;
- uint8_t write_state;
- uint8_t write_latch;
- uint8_t rw_mode;
- uint8_t mode;
- uint8_t bcd; /* not supported */
- uint8_t gate; /* timer start */
- int64_t count_load_time;
- /* irq handling */
- int64_t next_transition_time;
- QEMUTimer *irq_timer;
- int irq;
- int hvm_channel; /* Is this accelerated by HVM ? */
-} PITChannelState;
-
-struct PITState {
- PITChannelState channels[3];
-};
-
-static PITState pit_state;
-
-static void pit_irq_timer_update(PITChannelState *s, int64_t current_time);
-
-/* currently operate which channel for hvm use */
-int hvm_channel = -1;
-extern FILE *logfile;
-static int pit_get_count(PITChannelState *s)
-{
- uint64_t d;
- int counter;
-
- d = muldiv64(qemu_get_clock(vm_clock) - s->count_load_time, PIT_FREQ, ticks_per_sec);
- switch(s->mode) {
- case 0:
- case 1:
- case 4:
- case 5:
- counter = (s->count - d) & 0xffff;
- break;
- case 3:
- /* XXX: may be incorrect for odd counts */
- counter = s->count - ((2 * d) % s->count);
- break;
- default:
- counter = s->count - (d % s->count);
- break;
- }
- return counter;
-}
-
-/* get pit output bit */
-static int pit_get_out1(PITChannelState *s, int64_t current_time)
-{
- uint64_t d;
- int out;
-
- d = muldiv64(current_time - s->count_load_time, PIT_FREQ, ticks_per_sec);
- switch(s->mode) {
- default:
- case 0:
- out = (d >= s->count);
- break;
- case 1:
- out = (d < s->count);
- break;
- case 2:
- if ((d % s->count) == 0 && d != 0)
- out = 1;
- else
- out = 0;
- break;
- case 3:
- out = (d % s->count) < ((s->count + 1) >> 1);
- break;
- case 4:
- case 5:
- out = (d == s->count);
- break;
- }
- return out;
-}
-
-int pit_get_out(PITState *pit, int channel, int64_t current_time)
-{
- PITChannelState *s = &pit->channels[channel];
- return pit_get_out1(s, current_time);
-}
-
-/* return -1 if no transition will occur. */
-static int64_t pit_get_next_transition_time(PITChannelState *s,
- int64_t current_time)
-{
- uint64_t d, next_time, base;
- int period2;
-
- d = muldiv64(current_time - s->count_load_time, PIT_FREQ, ticks_per_sec);
- switch(s->mode) {
- default:
- case 0:
- case 1:
- if (d < s->count)
- next_time = s->count;
- else
- return -1;
- break;
- case 2:
- base = (d / s->count) * s->count;
- if ((d - base) == 0 && d != 0)
- next_time = base + s->count;
- else
- next_time = base + s->count + 1;
- break;
- case 3:
- base = (d / s->count) * s->count;
- period2 = ((s->count + 1) >> 1);
- if ((d - base) < period2)
- next_time = base + period2;
- else
- next_time = base + s->count;
- break;
- case 4:
- case 5:
- if (d < s->count)
- next_time = s->count;
- else if (d == s->count)
- next_time = s->count + 1;
- else
- return -1;
- break;
- }
- /* convert to timer units */
- next_time = s->count_load_time + muldiv64(next_time, ticks_per_sec, PIT_FREQ);
- /* fix potential rounding problems */
- /* XXX: better solution: use a clock at PIT_FREQ Hz */
- if (next_time <= current_time)
- next_time = current_time + 1;
- return next_time;
-}
-
-/* val must be 0 or 1 */
-void pit_set_gate(PITState *pit, int channel, int val)
-{
- PITChannelState *s = &pit->channels[channel];
-
- switch(s->mode) {
- default:
- case 0:
- case 4:
- /* XXX: just disable/enable counting */
- break;
- case 1:
- case 5:
- if (s->gate < val) {
- /* restart counting on rising edge */
- s->count_load_time = qemu_get_clock(vm_clock);
- pit_irq_timer_update(s, s->count_load_time);
- }
- break;
- case 2:
- case 3:
- if (s->gate < val) {
- /* restart counting on rising edge */
- s->count_load_time = qemu_get_clock(vm_clock);
- pit_irq_timer_update(s, s->count_load_time);
- }
- /* XXX: disable/enable counting */
- break;
- }
- s->gate = val;
-}
-
-int pit_get_gate(PITState *pit, int channel)
-{
- PITChannelState *s = &pit->channels[channel];
- return s->gate;
-}
-
-void pit_reset_hvm_vectors()
-{
- extern shared_iopage_t *shared_page;
- ioreq_t *req;
- int irq, i;
- PITChannelState *s;
-
- irq = 0;
-
- for(i = 0; i < 3; i++) {
- if (pit_state.channels[i].hvm_channel)
- break;
- }
-
- if (i == 3)
- return;
-
- /* Assumes just one HVM accelerated channel */
- hvm_channel = i;
- s = &pit_state.channels[hvm_channel];
- fprintf(logfile,
- "HVM_PIT:guest init pit channel %d!\n", hvm_channel);
- req = &shared_page->vcpu_iodata[0].vp_ioreq;
-
- req->state = STATE_IORESP_HOOK;
- /*
- * info passed to HV as following
- * -- init count:16 bit, timer vec:8 bit,
- * PIT channel(0~2):2 bit, rw mode:2 bit
- */
- req->u.data = s->count;
- req->u.data |= (irq << 16);
- req->u.data |= (hvm_channel << 24);
- req->u.data |= ((s->rw_mode) << 26);
- fprintf(logfile, "HVM_PIT:pass info 0x%"PRIx64" to HV!\n", req->u.data);
-}
-
-static inline void pit_load_count(PITChannelState *s, int val)
-{
- if (val == 0)
- val = 0x10000;
- s->count_load_time = qemu_get_clock(vm_clock);
- s->count = val;
-
- /* guest init this pit channel for periodic mode. we do not update related
- * timer so the channel never send intr from device model*/
- if (hvm_channel != -1 && s->mode == 2) {
- pit_reset_hvm_vectors();
- hvm_channel = -1;
- }
-
-/* pit_irq_timer_update(s, s->count_load_time);*/
-}
-
-/* if already latched, do not latch again */
-static void pit_latch_count(PITChannelState *s)
-{
- if (!s->count_latched) {
- s->latched_count = pit_get_count(s);
- s->count_latched = s->rw_mode;
- }
-}
-
-static void pit_ioport_write(void *opaque, uint32_t addr, uint32_t val)
-{
- PITState *pit = opaque;
- int channel, access;
- PITChannelState *s;
-
- addr &= 3;
- if (addr == 3) {
- channel = val >> 6;
- if (channel == 3) {
- /* read back command */
- for(channel = 0; channel < 3; channel++) {
- s = &pit->channels[channel];
- if (val & (2 << channel)) {
- if (!(val & 0x20)) {
- pit_latch_count(s);
- }
- if (!(val & 0x10) && !s->status_latched) {
- /* status latch */
- /* XXX: add BCD and null count */
- s->status = (pit_get_out1(s, qemu_get_clock(vm_clock)) << 7) |
- (s->rw_mode << 4) |
- (s->mode << 1) |
- s->bcd;
- s->status_latched = 1;
- }
- }
- }
- } else {
- s = &pit->channels[channel];
- access = (val >> 4) & 3;
- if (access == 0) {
- pit_latch_count(s);
- } else {
- s->rw_mode = access;
- s->read_state = access;
- s->write_state = access;
-
- s->mode = (val >> 1) & 7;
- s->bcd = val & 1;
- /* XXX: update irq timer ? */
- }
- }
- } else {
- s = &pit->channels[addr];
- s->hvm_channel = 1;
- hvm_channel = addr;
- switch(s->write_state) {
- default:
- case RW_STATE_LSB:
- pit_load_count(s, val);
- break;
- case RW_STATE_MSB:
- pit_load_count(s, val << 8);
- break;
- case RW_STATE_WORD0:
- s->write_latch = val;
- s->write_state = RW_STATE_WORD1;
- break;
- case RW_STATE_WORD1:
- pit_load_count(s, s->write_latch | (val << 8));
- s->write_state = RW_STATE_WORD0;
- break;
- }
- }
-}
-
-static uint32_t pit_ioport_read(void *opaque, uint32_t addr)
-{
- PITState *pit = opaque;
- int ret, count;
- PITChannelState *s;
-
- addr &= 3;
- s = &pit->channels[addr];
- if (s->status_latched) {
- s->status_latched = 0;
- ret = s->status;
- } else if (s->count_latched) {
- switch(s->count_latched) {
- default:
- case RW_STATE_LSB:
- ret = s->latched_count & 0xff;
- s->count_latched = 0;
- break;
- case RW_STATE_MSB:
- ret = s->latched_count >> 8;
- s->count_latched = 0;
- break;
- case RW_STATE_WORD0:
- ret = s->latched_count & 0xff;
- s->count_latched = RW_STATE_MSB;
- break;
- }
- } else {
- switch(s->read_state) {
- default:
- case RW_STATE_LSB:
- count = pit_get_count(s);
- ret = count & 0xff;
- break;
- case RW_STATE_MSB:
- count = pit_get_count(s);
- ret = (count >> 8) & 0xff;
- break;
- case RW_STATE_WORD0:
- count = pit_get_count(s);
- ret = count & 0xff;
- s->read_state = RW_STATE_WORD1;
- break;
- case RW_STATE_WORD1:
- count = pit_get_count(s);
- ret = (count >> 8) & 0xff;
- s->read_state = RW_STATE_WORD0;
- break;
- }
- }
- return ret;
-}
-
-static void pit_irq_timer_update(PITChannelState *s, int64_t current_time)
-{
- int64_t expire_time;
- int irq_level;
-
- if (!s->irq_timer)
- return;
- expire_time = pit_get_next_transition_time(s, current_time);
- irq_level = pit_get_out1(s, current_time);
- pic_set_irq(s->irq, irq_level);
-#ifdef DEBUG_PIT
- printf("irq_level=%d next_delay=%f\n",
- irq_level,
- (double)(expire_time - current_time) / ticks_per_sec);
-#endif
- s->next_transition_time = expire_time;
- if (expire_time != -1)
- qemu_mod_timer(s->irq_timer, expire_time);
- else
- qemu_del_timer(s->irq_timer);
-}
-
-static void pit_irq_timer(void *opaque)
-{
- PITChannelState *s = opaque;
-
- pit_irq_timer_update(s, s->next_transition_time);
-}
-
-static void pit_save(QEMUFile *f, void *opaque)
-{
- PITState *pit = opaque;
- PITChannelState *s;
- int i;
-
- for(i = 0; i < 3; i++) {
- s = &pit->channels[i];
- qemu_put_be32s(f, &s->count);
- qemu_put_be16s(f, &s->latched_count);
- qemu_put_8s(f, &s->count_latched);
- qemu_put_8s(f, &s->status_latched);
- qemu_put_8s(f, &s->status);
- qemu_put_8s(f, &s->read_state);
- qemu_put_8s(f, &s->write_state);
- qemu_put_8s(f, &s->write_latch);
- qemu_put_8s(f, &s->rw_mode);
- qemu_put_8s(f, &s->mode);
- qemu_put_8s(f, &s->bcd);
- qemu_put_8s(f, &s->gate);
- qemu_put_be64s(f, &s->count_load_time);
- if (s->irq_timer) {
- qemu_put_be64s(f, &s->next_transition_time);
- qemu_put_timer(f, s->irq_timer);
- }
- }
-}
-
-static int pit_load(QEMUFile *f, void *opaque, int version_id)
-{
- PITState *pit = opaque;
- PITChannelState *s;
- int i;
-
- if (version_id != 1)
- return -EINVAL;
-
- for(i = 0; i < 3; i++) {
- s = &pit->channels[i];
- qemu_get_be32s(f, &s->count);
- qemu_get_be16s(f, &s->latched_count);
- qemu_get_8s(f, &s->count_latched);
- qemu_get_8s(f, &s->status_latched);
- qemu_get_8s(f, &s->status);
- qemu_get_8s(f, &s->read_state);
- qemu_get_8s(f, &s->write_state);
- qemu_get_8s(f, &s->write_latch);
- qemu_get_8s(f, &s->rw_mode);
- qemu_get_8s(f, &s->mode);
- qemu_get_8s(f, &s->bcd);
- qemu_get_8s(f, &s->gate);
- qemu_get_be64s(f, &s->count_load_time);
- if (s->irq_timer) {
- qemu_get_be64s(f, &s->next_transition_time);
- qemu_get_timer(f, s->irq_timer);
- }
- }
- return 0;
-}
-
-static void pit_reset(void *opaque)
-{
- PITState *pit = opaque;
- PITChannelState *s;
- int i;
-
- for(i = 0;i < 3; i++) {
- s = &pit->channels[i];
- s->mode = 3;
- s->gate = (i != 2);
- pit_load_count(s, 0);
- }
-}
-
-PITState *pit_init(int base, int irq)
-{
- PITState *pit = &pit_state;
- PITChannelState *s;
-
- s = &pit->channels[0];
- /* the timer 0 is connected to an IRQ */
- s->irq_timer = qemu_new_timer(vm_clock, pit_irq_timer, s);
- s->irq = irq;
-
- register_savevm("i8254", base, 1, pit_save, pit_load, pit);
-
- qemu_register_reset(pit_reset, pit);
- register_ioport_write(base, 4, 1, pit_ioport_write, pit);
- register_ioport_read(base, 3, 1, pit_ioport_read, pit);
-
- pit_reset(pit);
-
- return pit;
-}
+++ /dev/null
-/*
- * QEMU 8259 interrupt controller emulation
- *
- * Copyright (c) 2003-2004 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "vl.h"
-#include <xenctrl.h>
-#include <xen/hvm/ioreq.h>
-
-/* debug PIC */
-//#define DEBUG_PIC
-
-//#define DEBUG_IRQ_LATENCY
-//#define DEBUG_IRQ_COUNT
-
-extern void pit_reset_hvm_vectors();
-
-typedef struct PicState {
- uint8_t last_irr; /* edge detection */
- uint8_t irr; /* interrupt request register */
- uint8_t imr; /* interrupt mask register */
- uint8_t isr; /* interrupt service register */
- uint8_t priority_add; /* highest irq priority */
- uint8_t irq_base;
- uint8_t read_reg_select;
- uint8_t poll;
- uint8_t special_mask;
- uint8_t init_state;
- uint8_t auto_eoi;
- uint8_t rotate_on_auto_eoi;
- uint8_t special_fully_nested_mode;
- uint8_t init4; /* true if 4 byte init */
- uint8_t elcr; /* PIIX edge/trigger selection*/
- uint8_t elcr_mask;
-} PicState;
-
-/* 0 is master pic, 1 is slave pic */
-static PicState pics[2];
-
-#if defined(DEBUG_PIC) || defined (DEBUG_IRQ_COUNT)
-static int irq_level[16];
-#endif
-#ifdef DEBUG_IRQ_COUNT
-static uint64_t irq_count[16];
-#endif
-
-/* set irq level. If an edge is detected, then the IRR is set to 1 */
-static inline void pic_set_irq1(PicState *s, int irq, int level)
-{
- int mask;
- mask = 1 << irq;
- if (s->elcr & mask) {
- /* level triggered */
- if (level) {
- s->irr |= mask;
- s->last_irr |= mask;
- } else {
- s->irr &= ~mask;
- s->last_irr &= ~mask;
- }
- } else {
- /* edge triggered */
- if (level) {
- if ((s->last_irr & mask) == 0)
- s->irr |= mask;
- s->last_irr |= mask;
- } else {
- s->last_irr &= ~mask;
- }
- }
-}
-
-/* return the highest priority found in mask (highest = smallest
- number). Return 8 if no irq */
-static inline int get_priority(PicState *s, int mask)
-{
- int priority;
- if (mask == 0)
- return 8;
- priority = 0;
- while ((mask & (1 << ((priority + s->priority_add) & 7))) == 0)
- priority++;
- return priority;
-}
-
-/* return the pic wanted interrupt. return -1 if none */
-static int pic_get_irq(PicState *s)
-{
- int mask, cur_priority, priority;
-
- mask = s->irr & ~s->imr;
- priority = get_priority(s, mask);
- if (priority == 8)
- return -1;
- /* compute current priority. If special fully nested mode on the
- master, the IRQ coming from the slave is not taken into account
- for the priority computation. */
- mask = s->isr;
- if (s->special_fully_nested_mode && s == &pics[0])
- mask &= ~(1 << 2);
- cur_priority = get_priority(s, mask);
- if (priority < cur_priority) {
- /* higher priority found: an irq should be generated */
- return (priority + s->priority_add) & 7;
- } else {
- return -1;
- }
-}
-
-/* pic[1] is connected to pin2 of pic[0] */
-#define CASCADE_IRQ 2
-
-extern shared_iopage_t *shared_page;
-
-static void xen_update_shared_imr(void)
-{
- uint8_t *pmask = (uint8_t *)shared_page->sp_global.pic_mask;
- int index;
-
- index = pics[0].irq_base/8;
- pmask[index] = pics[0].imr;
-
- index = pics[1].irq_base/8;
- pmask[index] = (pics[0].imr & (1 << CASCADE_IRQ)) ? 0xff : pics[1].imr;
-}
-
-static void xen_clear_shared_irr(void)
-{
- memset(shared_page->sp_global.pic_intr, 0, INTR_LEN);
-}
-
-/* raise irq to CPU if necessary. must be called every time the active
- irq may change */
-static void pic_update_irq(void)
-{
- int irq2, irq;
-
- /* first look at slave pic */
- irq2 = pic_get_irq(&pics[1]);
- if (irq2 >= 0) {
- /* if irq request by slave pic, signal master PIC */
- pic_set_irq1(&pics[0], 2, 1);
- pic_set_irq1(&pics[0], 2, 0);
- }
- /* look at requested irq */
- irq = pic_get_irq(&pics[0]);
- if (irq >= 0) {
-#if defined(DEBUG_PIC)
- {
- int i;
- for(i = 0; i < 2; i++) {
- printf("pic%d: imr=%x irr=%x padd=%d\n",
- i, pics[i].imr, pics[i].irr, pics[i].priority_add);
-
- }
- }
- printf("pic: cpu_interrupt\n");
-#endif
- cpu_interrupt(cpu_single_env, CPU_INTERRUPT_HARD);
- }
-
- xen_update_shared_imr();
-}
-
-#ifdef DEBUG_IRQ_LATENCY
-int64_t irq_time[16];
-#endif
-
-extern void ioapic_legacy_irq(int irq, int level);
-
-void pic_set_irq(int irq, int level)
-{
- ioapic_legacy_irq(irq, level);
-#if defined(DEBUG_PIC) || defined(DEBUG_IRQ_COUNT)
- if (level != irq_level[irq]) {
-#if defined(DEBUG_PIC)
- printf("pic_set_irq: irq=%d level=%d\n", irq, level);
-#endif
- irq_level[irq] = level;
-#ifdef DEBUG_IRQ_COUNT
- if (level == 1)
- irq_count[irq]++;
-#endif
- }
-#endif
-#ifdef DEBUG_IRQ_LATENCY
- if (level) {
- irq_time[irq] = qemu_get_clock(vm_clock);
- }
-#endif
- pic_set_irq1(&pics[irq >> 3], irq & 7, level);
- pic_update_irq();
-}
-
-/* acknowledge interrupt 'irq' */
-static inline void pic_intack(PicState *s, int irq)
-{
- if (s->auto_eoi) {
- if (s->rotate_on_auto_eoi)
- s->priority_add = (irq + 1) & 7;
- } else {
- s->isr |= (1 << irq);
- }
- /* We don't clear a level sensitive interrupt here */
- if (!(s->elcr & (1 << irq)))
- s->irr &= ~(1 << irq);
-}
-
-int cpu_get_pic_interrupt(CPUState *env)
-{
- int irq, irq2, intno;
-
- /* read the irq from the PIC */
-
- irq = pic_get_irq(&pics[0]);
- if (irq >= 0) {
- pic_intack(&pics[0], irq);
- if (irq == 2) {
- irq2 = pic_get_irq(&pics[1]);
- if (irq2 >= 0) {
- pic_intack(&pics[1], irq2);
- } else {
- /* spurious IRQ on slave controller */
- irq2 = 7;
- }
- intno = pics[1].irq_base + irq2;
- irq = irq2 + 8;
- } else {
- intno = pics[0].irq_base + irq;
- }
- } else {
- /* spurious IRQ on host controller */
- irq = 7;
- intno = pics[0].irq_base + irq;
- }
- pic_update_irq();
-
-#ifdef DEBUG_IRQ_LATENCY
- printf("IRQ%d latency=%0.3fus\n",
- irq,
- (double)(qemu_get_clock(vm_clock) - irq_time[irq]) * 1000000.0 / ticks_per_sec);
-#endif
-#if defined(DEBUG_PIC)
- printf("pic_interrupt: irq=%d\n", irq);
-#endif
- return intno;
-}
-
-int pic_irq2vec(int irq)
-{
- int vector = -1;
-
- if (irq >= 8 && irq <= 15) {
- if (pics[1].irq_base != 0xFF)
- vector = pics[1].irq_base + irq;
- } else if (irq != 2 && irq <= 7) {
- if (pics[0].irq_base != 0xFF)
- vector = pics[0].irq_base + irq;
- }
- return vector;
-}
-
-static void pic_reset(void *opaque)
-{
- PicState *s = opaque;
- int tmp;
-
- tmp = s->elcr_mask;
- memset(s, 0, sizeof(PicState));
- s->elcr_mask = tmp;
-
- xen_update_shared_imr();
- xen_clear_shared_irr();
-}
-
-static void pic_ioport_write(void *opaque, uint32_t addr, uint32_t val)
-{
- PicState *s = opaque;
- int priority, cmd, irq;
-
-#ifdef DEBUG_PIC
- printf("pic_write: addr=0x%02x val=0x%02x\n", addr, val);
-#endif
- addr &= 1;
- if (addr == 0) {
- if (val & 0x10) {
- /* init */
- pic_reset(s);
- /* deassert a pending interrupt */
- cpu_reset_interrupt(cpu_single_env, CPU_INTERRUPT_HARD);
-
- s->init_state = 1;
- s->init4 = val & 1;
- if (val & 0x02)
- hw_error("single mode not supported");
- if (val & 0x08)
- hw_error("level sensitive irq not supported");
- } else if (val & 0x08) {
- if (val & 0x04)
- s->poll = 1;
- if (val & 0x02)
- s->read_reg_select = val & 1;
- if (val & 0x40)
- s->special_mask = (val >> 5) & 1;
- } else {
- cmd = val >> 5;
- switch(cmd) {
- case 0:
- case 4:
- s->rotate_on_auto_eoi = cmd >> 2;
- break;
- case 1: /* end of interrupt */
- case 5:
- priority = get_priority(s, s->isr);
- if (priority != 8) {
- irq = (priority + s->priority_add) & 7;
- s->isr &= ~(1 << irq);
- if (cmd == 5)
- s->priority_add = (irq + 1) & 7;
- pic_update_irq();
- }
- break;
- case 3:
- irq = val & 7;
- s->isr &= ~(1 << irq);
- pic_update_irq();
- break;
- case 6:
- s->priority_add = (val + 1) & 7;
- pic_update_irq();
- break;
- case 7:
- irq = val & 7;
- s->isr &= ~(1 << irq);
- s->priority_add = (irq + 1) & 7;
- pic_update_irq();
- break;
- default:
- /* no operation */
- break;
- }
- }
- } else {
- switch(s->init_state) {
- case 0:
- /* normal mode */
- s->imr = val;
- pic_update_irq();
- break;
- case 1:
- s->irq_base = val & 0xf8;
- s->init_state = 2;
- pit_reset_hvm_vectors();
- break;
- case 2:
- if (s->init4) {
- s->init_state = 3;
- } else {
- s->init_state = 0;
- }
- break;
- case 3:
- s->special_fully_nested_mode = (val >> 4) & 1;
- s->auto_eoi = (val >> 1) & 1;
- s->init_state = 0;
- break;
- }
- }
-}
-
-static uint32_t pic_poll_read (PicState *s, uint32_t addr1)
-{
- int ret;
-
- ret = pic_get_irq(s);
- if (ret >= 0) {
- if (addr1 >> 7) {
- pics[0].isr &= ~(1 << 2);
- pics[0].irr &= ~(1 << 2);
- }
- s->irr &= ~(1 << ret);
- s->isr &= ~(1 << ret);
- if (addr1 >> 7 || ret != 2)
- pic_update_irq();
- } else {
- ret = 0x07;
- pic_update_irq();
- }
-
- return ret;
-}
-
-static uint32_t pic_ioport_read(void *opaque, uint32_t addr1)
-{
- PicState *s = opaque;
- unsigned int addr;
- int ret;
-
- addr = addr1;
- addr &= 1;
- if (s->poll) {
- ret = pic_poll_read(s, addr1);
- s->poll = 0;
- } else {
- if (addr == 0) {
- if (s->read_reg_select)
- ret = s->isr;
- else
- ret = s->irr;
- } else {
- ret = s->imr;
- }
- }
-#ifdef DEBUG_PIC
- printf("pic_read: addr=0x%02x val=0x%02x\n", addr1, ret);
-#endif
- return ret;
-}
-
-/* memory mapped interrupt status */
-uint32_t pic_intack_read(CPUState *env)
-{
- int ret;
-
- ret = pic_poll_read(&pics[0], 0x00);
- if (ret == 2)
- ret = pic_poll_read(&pics[1], 0x80) + 8;
- /* Prepare for ISR read */
- pics[0].read_reg_select = 1;
-
- return ret;
-}
-
-static void elcr_ioport_write(void *opaque, uint32_t addr, uint32_t val)
-{
- PicState *s = opaque;
- s->elcr = val & s->elcr_mask;
-}
-
-static uint32_t elcr_ioport_read(void *opaque, uint32_t addr1)
-{
- PicState *s = opaque;
- return s->elcr;
-}
-
-static void pic_save(QEMUFile *f, void *opaque)
-{
- PicState *s = opaque;
-
- qemu_put_8s(f, &s->last_irr);
- qemu_put_8s(f, &s->irr);
- qemu_put_8s(f, &s->imr);
- qemu_put_8s(f, &s->isr);
- qemu_put_8s(f, &s->priority_add);
- qemu_put_8s(f, &s->irq_base);
- qemu_put_8s(f, &s->read_reg_select);
- qemu_put_8s(f, &s->poll);
- qemu_put_8s(f, &s->special_mask);
- qemu_put_8s(f, &s->init_state);
- qemu_put_8s(f, &s->auto_eoi);
- qemu_put_8s(f, &s->rotate_on_auto_eoi);
- qemu_put_8s(f, &s->special_fully_nested_mode);
- qemu_put_8s(f, &s->init4);
- qemu_put_8s(f, &s->elcr);
-}
-
-static int pic_load(QEMUFile *f, void *opaque, int version_id)
-{
- PicState *s = opaque;
-
- if (version_id != 1)
- return -EINVAL;
-
- qemu_get_8s(f, &s->last_irr);
- qemu_get_8s(f, &s->irr);
- qemu_get_8s(f, &s->imr);
- qemu_get_8s(f, &s->isr);
- qemu_get_8s(f, &s->priority_add);
- qemu_get_8s(f, &s->irq_base);
- qemu_get_8s(f, &s->read_reg_select);
- qemu_get_8s(f, &s->poll);
- qemu_get_8s(f, &s->special_mask);
- qemu_get_8s(f, &s->init_state);
- qemu_get_8s(f, &s->auto_eoi);
- qemu_get_8s(f, &s->rotate_on_auto_eoi);
- qemu_get_8s(f, &s->special_fully_nested_mode);
- qemu_get_8s(f, &s->init4);
- qemu_get_8s(f, &s->elcr);
- return 0;
-}
-
-/* XXX: add generic master/slave system */
-static void pic_init1(int io_addr, int elcr_addr, PicState *s)
-{
- register_ioport_write(io_addr, 2, 1, pic_ioport_write, s);
- register_ioport_read(io_addr, 2, 1, pic_ioport_read, s);
- if (elcr_addr >= 0) {
- register_ioport_write(elcr_addr, 1, 1, elcr_ioport_write, s);
- register_ioport_read(elcr_addr, 1, 1, elcr_ioport_read, s);
- }
- register_savevm("i8259", io_addr, 1, pic_save, pic_load, s);
- qemu_register_reset(pic_reset, s);
-}
-
-void pic_info(void)
-{
- int i;
- PicState *s;
-
- for(i=0;i<2;i++) {
- s = &pics[i];
- term_printf("pic%d: irr=%02x imr=%02x isr=%02x hprio=%d irq_base=%02x rr_sel=%d elcr=%02x fnm=%d\n",
- i, s->irr, s->imr, s->isr, s->priority_add,
- s->irq_base, s->read_reg_select, s->elcr,
- s->special_fully_nested_mode);
- }
-}
-
-void irq_info(void)
-{
-#ifndef DEBUG_IRQ_COUNT
- term_printf("irq statistic code not compiled.\n");
-#else
- int i;
- int64_t count;
-
- term_printf("IRQ statistics:\n");
- for (i = 0; i < 16; i++) {
- count = irq_count[i];
- if (count > 0)
- term_printf("%2d: %lld\n", i, count);
- }
-#endif
-}
-
-void pic_init(void)
-{
- pic_init1(0x20, 0x4d0, &pics[0]);
- pic_init1(0xa0, 0x4d1, &pics[1]);
- pics[0].elcr_mask = 0xf8;
- pics[1].elcr_mask = 0xde;
- pics[0].irq_base = 0xff;
- pics[0].irq_base = 0xff;
-}
-
+++ /dev/null
-/* Xen 8259 stub for interrupt controller emulation
- *
- * Copyright (c) 2003-2004 Fabrice Bellard
- * Copyright (c) 2005 Intel corperation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "xenctrl.h"
-#include <xen/hvm/ioreq.h>
-#include <stdio.h>
-#include "cpu.h"
-#include "cpu-all.h"
-
-#include <vl.h>
-extern shared_iopage_t *shared_page;
-extern CPUState *global_env;
-void pic_set_irq(int irq, int level)
-{
- global_iodata_t *gio;
- int mask;
-
- gio = &shared_page->sp_global;
- mask = 1 << irq;
- if ( gio->pic_elcr & mask ) {
- /* level */
- if ( level ) {
- atomic_clear_bit(irq, &gio->pic_clear_irr);
- atomic_set_bit(irq, &gio->pic_irr);
- global_env->send_event = 1;
- }
- else {
- atomic_clear_bit(irq, &gio->pic_irr);
- atomic_set_bit(irq, &gio->pic_clear_irr);
- global_env->send_event = 1;
- }
- }
- else {
- /* edge */
- if ( level ) {
- if ( (mask & gio->pic_last_irr) == 0 ) {
- atomic_set_bit(irq, &gio->pic_irr);
- atomic_set_bit(irq, &gio->pic_last_irr);
- global_env->send_event = 1;
- }
- }
- else {
- atomic_clear_bit(irq, &gio->pic_last_irr);
- }
- }
-}
-
-void irq_info(void)
-{
- term_printf("irq statistic code not compiled.\n");
-}
-
-void pic_info(void)
-{
- term_printf("pic_infoi code not compiled.\n");
-}
-
-void pic_init(void)
-{
-}
-
+++ /dev/null
-/*
- * QEMU IDE disk and CD-ROM Emulator
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "vl.h"
-#include <pthread.h>
-
-/* debug IDE devices */
-//#define DEBUG_IDE
-//#define DEBUG_IDE_ATAPI
-
-/* Bits of HD_STATUS */
-#define ERR_STAT 0x01
-#define INDEX_STAT 0x02
-#define ECC_STAT 0x04 /* Corrected error */
-#define DRQ_STAT 0x08
-#define SEEK_STAT 0x10
-#define SRV_STAT 0x10
-#define WRERR_STAT 0x20
-#define READY_STAT 0x40
-#define BUSY_STAT 0x80
-
-/* Bits for HD_ERROR */
-#define MARK_ERR 0x01 /* Bad address mark */
-#define TRK0_ERR 0x02 /* couldn't find track 0 */
-#define ABRT_ERR 0x04 /* Command aborted */
-#define MCR_ERR 0x08 /* media change request */
-#define ID_ERR 0x10 /* ID field not found */
-#define MC_ERR 0x20 /* media changed */
-#define ECC_ERR 0x40 /* Uncorrectable ECC error */
-#define BBD_ERR 0x80 /* pre-EIDE meaning: block marked bad */
-#define ICRC_ERR 0x80 /* new meaning: CRC error during transfer */
-
-/* Bits of HD_NSECTOR */
-#define CD 0x01
-#define IO 0x02
-#define REL 0x04
-#define TAG_MASK 0xf8
-
-#define IDE_CMD_RESET 0x04
-#define IDE_CMD_DISABLE_IRQ 0x02
-
-/* ATA/ATAPI Commands pre T13 Spec */
-#define WIN_NOP 0x00
-/*
- * 0x01->0x02 Reserved
- */
-#define CFA_REQ_EXT_ERROR_CODE 0x03 /* CFA Request Extended Error Code */
-/*
- * 0x04->0x07 Reserved
- */
-#define WIN_SRST 0x08 /* ATAPI soft reset command */
-#define WIN_DEVICE_RESET 0x08
-/*
- * 0x09->0x0F Reserved
- */
-#define WIN_RECAL 0x10
-#define WIN_RESTORE WIN_RECAL
-/*
- * 0x10->0x1F Reserved
- */
-#define WIN_READ 0x20 /* 28-Bit */
-#define WIN_READ_ONCE 0x21 /* 28-Bit without retries */
-#define WIN_READ_LONG 0x22 /* 28-Bit */
-#define WIN_READ_LONG_ONCE 0x23 /* 28-Bit without retries */
-#define WIN_READ_EXT 0x24 /* 48-Bit */
-#define WIN_READDMA_EXT 0x25 /* 48-Bit */
-#define WIN_READDMA_QUEUED_EXT 0x26 /* 48-Bit */
-#define WIN_READ_NATIVE_MAX_EXT 0x27 /* 48-Bit */
-/*
- * 0x28
- */
-#define WIN_MULTREAD_EXT 0x29 /* 48-Bit */
-/*
- * 0x2A->0x2F Reserved
- */
-#define WIN_WRITE 0x30 /* 28-Bit */
-#define WIN_WRITE_ONCE 0x31 /* 28-Bit without retries */
-#define WIN_WRITE_LONG 0x32 /* 28-Bit */
-#define WIN_WRITE_LONG_ONCE 0x33 /* 28-Bit without retries */
-#define WIN_WRITE_EXT 0x34 /* 48-Bit */
-#define WIN_WRITEDMA_EXT 0x35 /* 48-Bit */
-#define WIN_WRITEDMA_QUEUED_EXT 0x36 /* 48-Bit */
-#define WIN_SET_MAX_EXT 0x37 /* 48-Bit */
-#define CFA_WRITE_SECT_WO_ERASE 0x38 /* CFA Write Sectors without erase */
-#define WIN_MULTWRITE_EXT 0x39 /* 48-Bit */
-/*
- * 0x3A->0x3B Reserved
- */
-#define WIN_WRITE_VERIFY 0x3C /* 28-Bit */
-/*
- * 0x3D->0x3F Reserved
- */
-#define WIN_VERIFY 0x40 /* 28-Bit - Read Verify Sectors */
-#define WIN_VERIFY_ONCE 0x41 /* 28-Bit - without retries */
-#define WIN_VERIFY_EXT 0x42 /* 48-Bit */
-/*
- * 0x43->0x4F Reserved
- */
-#define WIN_FORMAT 0x50
-/*
- * 0x51->0x5F Reserved
- */
-#define WIN_INIT 0x60
-/*
- * 0x61->0x5F Reserved
- */
-#define WIN_SEEK 0x70 /* 0x70-0x7F Reserved */
-#define CFA_TRANSLATE_SECTOR 0x87 /* CFA Translate Sector */
-#define WIN_DIAGNOSE 0x90
-#define WIN_SPECIFY 0x91 /* set drive geometry translation */
-#define WIN_DOWNLOAD_MICROCODE 0x92
-#define WIN_STANDBYNOW2 0x94
-#define WIN_STANDBY2 0x96
-#define WIN_SETIDLE2 0x97
-#define WIN_CHECKPOWERMODE2 0x98
-#define WIN_SLEEPNOW2 0x99
-/*
- * 0x9A VENDOR
- */
-#define WIN_PACKETCMD 0xA0 /* Send a packet command. */
-#define WIN_PIDENTIFY 0xA1 /* identify ATAPI device */
-#define WIN_QUEUED_SERVICE 0xA2
-#define WIN_SMART 0xB0 /* self-monitoring and reporting */
-#define CFA_ERASE_SECTORS 0xC0
-#define WIN_MULTREAD 0xC4 /* read sectors using multiple mode*/
-#define WIN_MULTWRITE 0xC5 /* write sectors using multiple mode */
-#define WIN_SETMULT 0xC6 /* enable/disable multiple mode */
-#define WIN_READDMA_QUEUED 0xC7 /* read sectors using Queued DMA transfers */
-#define WIN_READDMA 0xC8 /* read sectors using DMA transfers */
-#define WIN_READDMA_ONCE 0xC9 /* 28-Bit - without retries */
-#define WIN_WRITEDMA 0xCA /* write sectors using DMA transfers */
-#define WIN_WRITEDMA_ONCE 0xCB /* 28-Bit - without retries */
-#define WIN_WRITEDMA_QUEUED 0xCC /* write sectors using Queued DMA transfers */
-#define CFA_WRITE_MULTI_WO_ERASE 0xCD /* CFA Write multiple without erase */
-#define WIN_GETMEDIASTATUS 0xDA
-#define WIN_ACKMEDIACHANGE 0xDB /* ATA-1, ATA-2 vendor */
-#define WIN_POSTBOOT 0xDC
-#define WIN_PREBOOT 0xDD
-#define WIN_DOORLOCK 0xDE /* lock door on removable drives */
-#define WIN_DOORUNLOCK 0xDF /* unlock door on removable drives */
-#define WIN_STANDBYNOW1 0xE0
-#define WIN_IDLEIMMEDIATE 0xE1 /* force drive to become "ready" */
-#define WIN_STANDBY 0xE2 /* Set device in Standby Mode */
-#define WIN_SETIDLE1 0xE3
-#define WIN_READ_BUFFER 0xE4 /* force read only 1 sector */
-#define WIN_CHECKPOWERMODE1 0xE5
-#define WIN_SLEEPNOW1 0xE6
-#define WIN_FLUSH_CACHE 0xE7
-#define WIN_WRITE_BUFFER 0xE8 /* force write only 1 sector */
-#define WIN_WRITE_SAME 0xE9 /* read ata-2 to use */
- /* SET_FEATURES 0x22 or 0xDD */
-#define WIN_FLUSH_CACHE_EXT 0xEA /* 48-Bit */
-#define WIN_IDENTIFY 0xEC /* ask drive to identify itself */
-#define WIN_MEDIAEJECT 0xED
-#define WIN_IDENTIFY_DMA 0xEE /* same as WIN_IDENTIFY, but DMA */
-#define WIN_SETFEATURES 0xEF /* set special drive features */
-#define EXABYTE_ENABLE_NEST 0xF0
-#define WIN_SECURITY_SET_PASS 0xF1
-#define WIN_SECURITY_UNLOCK 0xF2
-#define WIN_SECURITY_ERASE_PREPARE 0xF3
-#define WIN_SECURITY_ERASE_UNIT 0xF4
-#define WIN_SECURITY_FREEZE_LOCK 0xF5
-#define WIN_SECURITY_DISABLE 0xF6
-#define WIN_READ_NATIVE_MAX 0xF8 /* return the native maximum address */
-#define WIN_SET_MAX 0xF9
-#define DISABLE_SEAGATE 0xFB
-
-/* set to 1 set disable mult support */
-#define MAX_MULT_SECTORS 16
-
-/* ATAPI defines */
-
-#define ATAPI_PACKET_SIZE 12
-
-/* The generic packet command opcodes for CD/DVD Logical Units,
- * From Table 57 of the SFF8090 Ver. 3 (Mt. Fuji) draft standard. */
-#define GPCMD_BLANK 0xa1
-#define GPCMD_CLOSE_TRACK 0x5b
-#define GPCMD_FLUSH_CACHE 0x35
-#define GPCMD_FORMAT_UNIT 0x04
-#define GPCMD_GET_CONFIGURATION 0x46
-#define GPCMD_GET_EVENT_STATUS_NOTIFICATION 0x4a
-#define GPCMD_GET_PERFORMANCE 0xac
-#define GPCMD_INQUIRY 0x12
-#define GPCMD_LOAD_UNLOAD 0xa6
-#define GPCMD_MECHANISM_STATUS 0xbd
-#define GPCMD_MODE_SELECT_10 0x55
-#define GPCMD_MODE_SENSE_10 0x5a
-#define GPCMD_PAUSE_RESUME 0x4b
-#define GPCMD_PLAY_AUDIO_10 0x45
-#define GPCMD_PLAY_AUDIO_MSF 0x47
-#define GPCMD_PLAY_AUDIO_TI 0x48
-#define GPCMD_PLAY_CD 0xbc
-#define GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL 0x1e
-#define GPCMD_READ_10 0x28
-#define GPCMD_READ_12 0xa8
-#define GPCMD_READ_CDVD_CAPACITY 0x25
-#define GPCMD_READ_CD 0xbe
-#define GPCMD_READ_CD_MSF 0xb9
-#define GPCMD_READ_DISC_INFO 0x51
-#define GPCMD_READ_DVD_STRUCTURE 0xad
-#define GPCMD_READ_FORMAT_CAPACITIES 0x23
-#define GPCMD_READ_HEADER 0x44
-#define GPCMD_READ_TRACK_RZONE_INFO 0x52
-#define GPCMD_READ_SUBCHANNEL 0x42
-#define GPCMD_READ_TOC_PMA_ATIP 0x43
-#define GPCMD_REPAIR_RZONE_TRACK 0x58
-#define GPCMD_REPORT_KEY 0xa4
-#define GPCMD_REQUEST_SENSE 0x03
-#define GPCMD_RESERVE_RZONE_TRACK 0x53
-#define GPCMD_SCAN 0xba
-#define GPCMD_SEEK 0x2b
-#define GPCMD_SEND_DVD_STRUCTURE 0xad
-#define GPCMD_SEND_EVENT 0xa2
-#define GPCMD_SEND_KEY 0xa3
-#define GPCMD_SEND_OPC 0x54
-#define GPCMD_SET_READ_AHEAD 0xa7
-#define GPCMD_SET_STREAMING 0xb6
-#define GPCMD_START_STOP_UNIT 0x1b
-#define GPCMD_STOP_PLAY_SCAN 0x4e
-#define GPCMD_TEST_UNIT_READY 0x00
-#define GPCMD_VERIFY_10 0x2f
-#define GPCMD_WRITE_10 0x2a
-#define GPCMD_WRITE_AND_VERIFY_10 0x2e
-/* This is listed as optional in ATAPI 2.6, but is (curiously)
- * missing from Mt. Fuji, Table 57. It _is_ mentioned in Mt. Fuji
- * Table 377 as an MMC command for SCSi devices though... Most ATAPI
- * drives support it. */
-#define GPCMD_SET_SPEED 0xbb
-/* This seems to be a SCSI specific CD-ROM opcode
- * to play data at track/index */
-#define GPCMD_PLAYAUDIO_TI 0x48
-/*
- * From MS Media Status Notification Support Specification. For
- * older drives only.
- */
-#define GPCMD_GET_MEDIA_STATUS 0xda
-
-/* Mode page codes for mode sense/set */
-#define GPMODE_R_W_ERROR_PAGE 0x01
-#define GPMODE_WRITE_PARMS_PAGE 0x05
-#define GPMODE_AUDIO_CTL_PAGE 0x0e
-#define GPMODE_POWER_PAGE 0x1a
-#define GPMODE_FAULT_FAIL_PAGE 0x1c
-#define GPMODE_TO_PROTECT_PAGE 0x1d
-#define GPMODE_CAPABILITIES_PAGE 0x2a
-#define GPMODE_ALL_PAGES 0x3f
-/* Not in Mt. Fuji, but in ATAPI 2.6 -- depricated now in favor
- * of MODE_SENSE_POWER_PAGE */
-#define GPMODE_CDROM_PAGE 0x0d
-
-#define ATAPI_INT_REASON_CD 0x01 /* 0 = data transfer */
-#define ATAPI_INT_REASON_IO 0x02 /* 1 = transfer to the host */
-#define ATAPI_INT_REASON_REL 0x04
-#define ATAPI_INT_REASON_TAG 0xf8
-
-/* same constants as bochs */
-#define ASC_ILLEGAL_OPCODE 0x20
-#define ASC_LOGICAL_BLOCK_OOR 0x21
-#define ASC_INV_FIELD_IN_CMD_PACKET 0x24
-#define ASC_MEDIUM_NOT_PRESENT 0x3a
-#define ASC_SAVING_PARAMETERS_NOT_SUPPORTED 0x39
-
-#define SENSE_NONE 0
-#define SENSE_NOT_READY 2
-#define SENSE_ILLEGAL_REQUEST 5
-#define SENSE_UNIT_ATTENTION 6
-
-struct IDEState;
-
-typedef void EndTransferFunc(struct IDEState *);
-
-/* NOTE: IDEState represents in fact one drive */
-typedef struct IDEState {
- /* ide config */
- int is_cdrom;
- int cylinders, heads, sectors;
- int64_t nb_sectors;
- int mult_sectors;
- int irq;
- openpic_t *openpic;
- PCIDevice *pci_dev;
- struct BMDMAState *bmdma;
- int drive_serial;
- /* ide regs */
- uint8_t feature;
- uint8_t error;
- uint16_t nsector; /* 0 is 256 to ease computations */
- uint8_t sector;
- uint8_t lcyl;
- uint8_t hcyl;
- uint8_t select;
- uint8_t status;
- /* 0x3f6 command, only meaningful for drive 0 */
- uint8_t cmd;
- /* depends on bit 4 in select, only meaningful for drive 0 */
- struct IDEState *cur_drive;
- BlockDriverState *bs;
- /* ATAPI specific */
- uint8_t sense_key;
- uint8_t asc;
- int packet_transfer_size;
- int elementary_transfer_size;
- int io_buffer_index;
- int lba;
- int cd_sector_size;
- int atapi_dma; /* true if dma is requested for the packet cmd */
- /* ATA DMA state */
- int io_buffer_size;
- /* PIO transfer handling */
- int req_nb_sectors; /* number of sectors per interrupt */
- EndTransferFunc *end_transfer_func;
- uint8_t *data_ptr;
- uint8_t *data_end;
- uint8_t io_buffer[MAX_MULT_SECTORS*512 + 4];
-} IDEState;
-
-#define BM_STATUS_DMAING 0x01
-#define BM_STATUS_ERROR 0x02
-#define BM_STATUS_INT 0x04
-
-#define BM_CMD_START 0x01
-#define BM_CMD_READ 0x08
-
-typedef int IDEDMAFunc(IDEState *s,
- target_phys_addr_t phys_addr,
- int transfer_size1);
-
-typedef struct BMDMAState {
- uint8_t cmd;
- uint8_t status;
- uint32_t addr;
- /* current transfer state */
- IDEState *ide_if;
- IDEDMAFunc *dma_cb;
-} BMDMAState;
-
-typedef struct PCIIDEState {
- PCIDevice dev;
- IDEState ide_if[4];
- BMDMAState bmdma[2];
-} PCIIDEState;
-
-#define DMA_MULTI_THREAD
-
-#ifdef DMA_MULTI_THREAD
-
-static int file_pipes[2];
-
-static void ide_dma_loop(BMDMAState *bm);
-static void dma_thread_loop(BMDMAState *bm);
-
-static void *dma_thread_func(void* opaque)
-{
- BMDMAState* req;
-
- while (read(file_pipes[0], &req, sizeof(req))) {
- dma_thread_loop(req);
- }
-
- return NULL;
-}
-
-static void dma_create_thread()
-{
- pthread_t tid;
- int rt;
-
- if (pipe(file_pipes) != 0){
- fprintf(stderr, "create pipe failed\n");
- exit(1);
- }
-
- if ( (rt = pthread_create(&tid, NULL, dma_thread_func, NULL)) ) {
- fprintf(stderr, "Oops, dma thread creation failed, errno=%d\n", rt);
- exit(1);
- }
-
- if ( (rt = pthread_detach(tid)) ) {
- fprintf(stderr, "Oops, dma thread detachment failed, errno=%d\n", rt);
- exit(1);
- }
-}
-#endif //DMA_MULTI_THREAD
-
-static void ide_dma_start(IDEState *s, IDEDMAFunc *dma_cb);
-
-static void padstr(char *str, const char *src, int len)
-{
- int i, v;
- for(i = 0; i < len; i++) {
- if (*src)
- v = *src++;
- else
- v = ' ';
- *(char *)((long)str ^ 1) = v;
- str++;
- }
-}
-
-static void padstr8(uint8_t *buf, int buf_size, const char *src)
-{
- int i;
- for(i = 0; i < buf_size; i++) {
- if (*src)
- buf[i] = *src++;
- else
- buf[i] = ' ';
- }
-}
-
-static void put_le16(uint16_t *p, unsigned int v)
-{
- *p = cpu_to_le16(v);
-}
-
-static void ide_identify(IDEState *s)
-{
- uint16_t *p;
- unsigned int oldsize;
- char buf[20];
-
- memset(s->io_buffer, 0, 512);
- p = (uint16_t *)s->io_buffer;
- put_le16(p + 0, 0x0040);
- put_le16(p + 1, s->cylinders);
- put_le16(p + 3, s->heads);
- put_le16(p + 4, 512 * s->sectors); /* XXX: retired, remove ? */
- put_le16(p + 5, 512); /* XXX: retired, remove ? */
- put_le16(p + 6, s->sectors);
- snprintf(buf, sizeof(buf), "QM%05d", s->drive_serial);
- padstr((uint8_t *)(p + 10), buf, 20); /* serial number */
- put_le16(p + 20, 3); /* XXX: retired, remove ? */
- put_le16(p + 21, 512); /* cache size in sectors */
- put_le16(p + 22, 4); /* ecc bytes */
- padstr((uint8_t *)(p + 23), QEMU_VERSION, 8); /* firmware version */
- padstr((uint8_t *)(p + 27), "QEMU HARDDISK", 40); /* model */
-#if MAX_MULT_SECTORS > 1
- put_le16(p + 47, 0x8000 | MAX_MULT_SECTORS);
-#endif
- put_le16(p + 48, 1); /* dword I/O */
- put_le16(p + 49, 1 << 9 | 1 << 8); /* DMA and LBA supported */
- put_le16(p + 51, 0x200); /* PIO transfer cycle */
- put_le16(p + 52, 0x200); /* DMA transfer cycle */
- put_le16(p + 53, 1 | 1 << 2); /* words 54-58,88 are valid */
- put_le16(p + 54, s->cylinders);
- put_le16(p + 55, s->heads);
- put_le16(p + 56, s->sectors);
- oldsize = s->cylinders * s->heads * s->sectors;
- put_le16(p + 57, oldsize);
- put_le16(p + 58, oldsize >> 16);
- if (s->mult_sectors)
- put_le16(p + 59, 0x100 | s->mult_sectors);
- put_le16(p + 60, s->nb_sectors);
- put_le16(p + 61, s->nb_sectors >> 16);
- put_le16(p + 63, 0x07);
- put_le16(p + 80, (1 << 1) | (1 << 2));
- put_le16(p + 82, (1 << 14));
- put_le16(p + 83, (1 << 14));
- put_le16(p + 84, (1 << 14));
- put_le16(p + 85, (1 << 14));
- put_le16(p + 86, 0);
- put_le16(p + 87, (1 << 14));
- put_le16(p + 88, 0x1f | (1 << 13));
- put_le16(p + 93, 1 | (1 << 14) | 0x2000 | 0x4000);
-}
-
-static void ide_atapi_identify(IDEState *s)
-{
- uint16_t *p;
- char buf[20];
-
- memset(s->io_buffer, 0, 512);
- p = (uint16_t *)s->io_buffer;
- /* Removable CDROM, 50us response, 12 byte packets */
- put_le16(p + 0, (2 << 14) | (5 << 8) | (1 << 7) | (2 << 5) | (0 << 0));
- snprintf(buf, sizeof(buf), "QM%05d", s->drive_serial);
- padstr((uint8_t *)(p + 10), buf, 20); /* serial number */
- put_le16(p + 20, 3); /* buffer type */
- put_le16(p + 21, 512); /* cache size in sectors */
- put_le16(p + 22, 4); /* ecc bytes */
- padstr((uint8_t *)(p + 23), QEMU_VERSION, 8); /* firmware version */
- padstr((uint8_t *)(p + 27), "QEMU CD-ROM", 40); /* model */
- put_le16(p + 48, 1); /* dword I/O (XXX: should not be set on CDROM) */
- put_le16(p + 49, 1 << 9); /* LBA supported, no DMA */
- put_le16(p + 53, 3); /* words 64-70, 54-58 valid */
- put_le16(p + 63, 0x07); /* Multi-word DMA mode 2 */
- put_le16(p + 64, 1); /* PIO modes */
- put_le16(p + 65, 0xb4); /* minimum DMA multiword tx cycle time */
- put_le16(p + 66, 0xb4); /* recommended DMA multiword tx cycle time */
- put_le16(p + 67, 0x12c); /* minimum PIO cycle time without flow control */
- put_le16(p + 68, 0xb4); /* minimum PIO cycle time with IORDY flow control */
-
- put_le16(p + 71, 30); /* in ns */
- put_le16(p + 72, 30); /* in ns */
-
- put_le16(p + 80, 0x1e); /* support up to ATA/ATAPI-4 */
-}
-
-static void ide_set_signature(IDEState *s)
-{
- s->select &= 0xf0; /* clear head */
- /* put signature */
- s->nsector = 1;
- s->sector = 1;
- if (s->is_cdrom) {
- s->lcyl = 0x14;
- s->hcyl = 0xeb;
- } else if (s->bs) {
- s->lcyl = 0;
- s->hcyl = 0;
- } else {
- s->lcyl = 0xff;
- s->hcyl = 0xff;
- }
-}
-
-static inline void ide_abort_command(IDEState *s)
-{
- s->status = READY_STAT | ERR_STAT;
- s->error = ABRT_ERR;
-}
-
-static inline void ide_set_irq(IDEState *s)
-{
- if (!(s->cmd & IDE_CMD_DISABLE_IRQ)) {
-#ifdef TARGET_PPC
- if (s->openpic)
- openpic_set_irq(s->openpic, s->irq, 1);
- else
-#endif
- if (s->irq == 16)
- pci_set_irq(s->pci_dev, 0, 1);
- else
- pic_set_irq(s->irq, 1);
- }
-}
-
-/* prepare data transfer and tell what to do after */
-static void ide_transfer_start(IDEState *s, uint8_t *buf, int size,
- EndTransferFunc *end_transfer_func)
-{
- s->end_transfer_func = end_transfer_func;
- s->data_ptr = buf;
- s->data_end = buf + size;
- s->status |= DRQ_STAT;
-}
-
-static void ide_transfer_stop(IDEState *s)
-{
- s->end_transfer_func = ide_transfer_stop;
- s->data_ptr = s->io_buffer;
- s->data_end = s->io_buffer;
- s->status &= ~DRQ_STAT;
-}
-
-static int64_t ide_get_sector(IDEState *s)
-{
- int64_t sector_num;
- if (s->select & 0x40) {
- /* lba */
- sector_num = ((s->select & 0x0f) << 24) | (s->hcyl << 16) |
- (s->lcyl << 8) | s->sector;
- } else {
- sector_num = ((s->hcyl << 8) | s->lcyl) * s->heads * s->sectors +
- (s->select & 0x0f) * s->sectors +
- (s->sector - 1);
- }
- return sector_num;
-}
-
-static void ide_set_sector(IDEState *s, int64_t sector_num)
-{
- unsigned int cyl, r;
- if (s->select & 0x40) {
- s->select = (s->select & 0xf0) | (sector_num >> 24);
- s->hcyl = (sector_num >> 16);
- s->lcyl = (sector_num >> 8);
- s->sector = (sector_num);
- } else {
- cyl = sector_num / (s->heads * s->sectors);
- r = sector_num % (s->heads * s->sectors);
- s->hcyl = cyl >> 8;
- s->lcyl = cyl;
- s->select = (s->select & 0xf0) | ((r / s->sectors) & 0x0f);
- s->sector = (r % s->sectors) + 1;
- }
-}
-
-static void ide_sector_read(IDEState *s)
-{
- int64_t sector_num;
- int ret, n;
-
- s->status = READY_STAT | SEEK_STAT;
- s->error = 0; /* not needed by IDE spec, but needed by Windows */
- sector_num = ide_get_sector(s);
- n = s->nsector;
- if (n == 0) {
- /* no more sector to read from disk */
- ide_transfer_stop(s);
- } else {
-#if defined(DEBUG_IDE)
- printf("read sector=%Ld\n", sector_num);
-#endif
- if (n > s->req_nb_sectors)
- n = s->req_nb_sectors;
- ret = bdrv_read(s->bs, sector_num, s->io_buffer, n);
- ide_transfer_start(s, s->io_buffer, 512 * n, ide_sector_read);
- ide_set_irq(s);
- ide_set_sector(s, sector_num + n);
- s->nsector -= n;
- }
-}
-
-static int ide_read_dma_cb(IDEState *s,
- target_phys_addr_t phys_addr,
- int transfer_size1)
-{
- int len, transfer_size, n;
- int64_t sector_num;
-
- transfer_size = transfer_size1;
- while (transfer_size > 0) {
- len = s->io_buffer_size - s->io_buffer_index;
- if (len <= 0) {
- /* transfert next data */
- n = s->nsector;
- if (n == 0)
- break;
- if (n > MAX_MULT_SECTORS)
- n = MAX_MULT_SECTORS;
- sector_num = ide_get_sector(s);
- bdrv_read(s->bs, sector_num, s->io_buffer, n);
- s->io_buffer_index = 0;
- s->io_buffer_size = n * 512;
- len = s->io_buffer_size;
- sector_num += n;
- ide_set_sector(s, sector_num);
- s->nsector -= n;
- }
- if (len > transfer_size)
- len = transfer_size;
- cpu_physical_memory_write(phys_addr,
- s->io_buffer + s->io_buffer_index, len);
- s->io_buffer_index += len;
- transfer_size -= len;
- phys_addr += len;
- }
- if (s->io_buffer_index >= s->io_buffer_size && s->nsector == 0) {
- s->status = READY_STAT | SEEK_STAT;
-#ifdef DEBUG_IDE_ATAPI
- printf("dma status=0x%x\n", s->status);
-#endif
- return 0;
- }
- return transfer_size1 - transfer_size;
-}
-
-static void ide_sector_read_dma(IDEState *s)
-{
- s->status = READY_STAT | SEEK_STAT | DRQ_STAT;
- s->io_buffer_index = 0;
- s->io_buffer_size = 0;
- ide_dma_start(s, ide_read_dma_cb);
-}
-
-static void ide_sector_write(IDEState *s)
-{
- int64_t sector_num;
- int ret, n, n1;
-
- s->status = READY_STAT | SEEK_STAT;
- sector_num = ide_get_sector(s);
-#if defined(DEBUG_IDE)
- printf("write sector=%Ld\n", sector_num);
-#endif
- n = s->nsector;
- if (n > s->req_nb_sectors)
- n = s->req_nb_sectors;
- ret = bdrv_write(s->bs, sector_num, s->io_buffer, n);
- s->nsector -= n;
- if (s->nsector == 0) {
- /* no more sector to write */
- ide_transfer_stop(s);
- } else {
- n1 = s->nsector;
- if (n1 > s->req_nb_sectors)
- n1 = s->req_nb_sectors;
- ide_transfer_start(s, s->io_buffer, 512 * n1, ide_sector_write);
- }
- ide_set_sector(s, sector_num + n);
- ide_set_irq(s);
-}
-
-static int ide_write_dma_cb(IDEState *s,
- target_phys_addr_t phys_addr,
- int transfer_size1)
-{
- int len, transfer_size, n;
- int64_t sector_num;
-
- transfer_size = transfer_size1;
- for(;;) {
- len = s->io_buffer_size - s->io_buffer_index;
- if (len == 0) {
- n = s->io_buffer_size >> 9;
- sector_num = ide_get_sector(s);
- bdrv_write(s->bs, sector_num, s->io_buffer,
- s->io_buffer_size >> 9);
- sector_num += n;
- ide_set_sector(s, sector_num);
- s->nsector -= n;
- n = s->nsector;
- if (n == 0) {
- /* end of transfer */
- s->status = READY_STAT | SEEK_STAT;
- return 0;
- }
- if (n > MAX_MULT_SECTORS)
- n = MAX_MULT_SECTORS;
- s->io_buffer_index = 0;
- s->io_buffer_size = n * 512;
- len = s->io_buffer_size;
- }
- if (transfer_size <= 0)
- break;
- if (len > transfer_size)
- len = transfer_size;
- cpu_physical_memory_read(phys_addr,
- s->io_buffer + s->io_buffer_index, len);
- s->io_buffer_index += len;
- transfer_size -= len;
- phys_addr += len;
- }
- return transfer_size1 - transfer_size;
-}
-
-static void ide_sector_write_dma(IDEState *s)
-{
- int n;
- s->status = READY_STAT | SEEK_STAT | DRQ_STAT;
- n = s->nsector;
- if (n > MAX_MULT_SECTORS)
- n = MAX_MULT_SECTORS;
- s->io_buffer_index = 0;
- s->io_buffer_size = n * 512;
- ide_dma_start(s, ide_write_dma_cb);
-}
-
-static void ide_atapi_cmd_ok(IDEState *s)
-{
- s->error = 0;
- s->status = READY_STAT;
- s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD;
- ide_set_irq(s);
-}
-
-static void ide_atapi_cmd_error(IDEState *s, int sense_key, int asc)
-{
-#ifdef DEBUG_IDE_ATAPI
- printf("atapi_cmd_error: sense=0x%x asc=0x%x\n", sense_key, asc);
-#endif
- s->error = sense_key << 4;
- s->status = READY_STAT | ERR_STAT;
- s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD;
- s->sense_key = sense_key;
- s->asc = asc;
- ide_set_irq(s);
-}
-
-static inline void cpu_to_ube16(uint8_t *buf, int val)
-{
- buf[0] = val >> 8;
- buf[1] = val;
-}
-
-static inline void cpu_to_ube32(uint8_t *buf, unsigned int val)
-{
- buf[0] = val >> 24;
- buf[1] = val >> 16;
- buf[2] = val >> 8;
- buf[3] = val;
-}
-
-static inline int ube16_to_cpu(const uint8_t *buf)
-{
- return (buf[0] << 8) | buf[1];
-}
-
-static inline int ube32_to_cpu(const uint8_t *buf)
-{
- return (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
-}
-
-static void lba_to_msf(uint8_t *buf, int lba)
-{
- lba += 150;
- buf[0] = (lba / 75) / 60;
- buf[1] = (lba / 75) % 60;
- buf[2] = lba % 75;
-}
-
-static void cd_read_sector(BlockDriverState *bs, int lba, uint8_t *buf,
- int sector_size)
-{
- switch(sector_size) {
- case 2048:
- bdrv_read(bs, (int64_t)lba << 2, buf, 4);
- break;
- case 2352:
- /* sync bytes */
- buf[0] = 0x00;
- memset(buf + 1, 0xff, 11);
- buf += 12;
- /* MSF */
- lba_to_msf(buf, lba);
- buf[3] = 0x01; /* mode 1 data */
- buf += 4;
- /* data */
- bdrv_read(bs, (int64_t)lba << 2, buf, 4);
- buf += 2048;
- /* ECC */
- memset(buf, 0, 288);
- break;
- default:
- break;
- }
-}
-
-/* The whole ATAPI transfer logic is handled in this function */
-static void ide_atapi_cmd_reply_end(IDEState *s)
-{
- int byte_count_limit, size;
-#ifdef DEBUG_IDE_ATAPI
- printf("reply: tx_size=%d elem_tx_size=%d index=%d\n",
- s->packet_transfer_size,
- s->elementary_transfer_size,
- s->io_buffer_index);
-#endif
- if (s->packet_transfer_size <= 0) {
- /* end of transfer */
- ide_transfer_stop(s);
- s->status = READY_STAT;
- s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD;
- ide_set_irq(s);
-#ifdef DEBUG_IDE_ATAPI
- printf("status=0x%x\n", s->status);
-#endif
- } else {
- /* see if a new sector must be read */
- if (s->lba != -1 && s->io_buffer_index >= s->cd_sector_size) {
- cd_read_sector(s->bs, s->lba, s->io_buffer, s->cd_sector_size);
- s->lba++;
- s->io_buffer_index = 0;
- }
- if (s->elementary_transfer_size > 0) {
- /* there are some data left to transmit in this elementary
- transfer */
- size = s->cd_sector_size - s->io_buffer_index;
- if (size > s->elementary_transfer_size)
- size = s->elementary_transfer_size;
- ide_transfer_start(s, s->io_buffer + s->io_buffer_index,
- size, ide_atapi_cmd_reply_end);
- s->packet_transfer_size -= size;
- s->elementary_transfer_size -= size;
- s->io_buffer_index += size;
- } else {
- /* a new transfer is needed */
- s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO;
- byte_count_limit = s->lcyl | (s->hcyl << 8);
-#ifdef DEBUG_IDE_ATAPI
- printf("byte_count_limit=%d\n", byte_count_limit);
-#endif
- if (byte_count_limit == 0xffff)
- byte_count_limit--;
- size = s->packet_transfer_size;
- if (size > byte_count_limit) {
- /* byte count limit must be even if this case */
- if (byte_count_limit & 1)
- byte_count_limit--;
- size = byte_count_limit;
- }
- s->lcyl = size;
- s->hcyl = size >> 8;
- s->elementary_transfer_size = size;
- /* we cannot transmit more than one sector at a time */
- if (s->lba != -1) {
- if (size > (s->cd_sector_size - s->io_buffer_index))
- size = (s->cd_sector_size - s->io_buffer_index);
- }
- ide_transfer_start(s, s->io_buffer + s->io_buffer_index,
- size, ide_atapi_cmd_reply_end);
- s->packet_transfer_size -= size;
- s->elementary_transfer_size -= size;
- s->io_buffer_index += size;
- ide_set_irq(s);
-#ifdef DEBUG_IDE_ATAPI
- printf("status=0x%x\n", s->status);
-#endif
- }
- }
-}
-
-/* send a reply of 'size' bytes in s->io_buffer to an ATAPI command */
-static void ide_atapi_cmd_reply(IDEState *s, int size, int max_size)
-{
- if (size > max_size)
- size = max_size;
- s->lba = -1; /* no sector read */
- s->packet_transfer_size = size;
- s->elementary_transfer_size = 0;
- s->io_buffer_index = 0;
-
- s->status = READY_STAT;
- ide_atapi_cmd_reply_end(s);
-}
-
-/* start a CD-CDROM read command */
-static void ide_atapi_cmd_read_pio(IDEState *s, int lba, int nb_sectors,
- int sector_size)
-{
- s->lba = lba;
- s->packet_transfer_size = nb_sectors * sector_size;
- s->elementary_transfer_size = 0;
- s->io_buffer_index = sector_size;
- s->cd_sector_size = sector_size;
-
- s->status = READY_STAT;
- ide_atapi_cmd_reply_end(s);
-}
-
-/* ATAPI DMA support */
-static int ide_atapi_cmd_read_dma_cb(IDEState *s,
- target_phys_addr_t phys_addr,
- int transfer_size1)
-{
- int len, transfer_size;
-
- transfer_size = transfer_size1;
- while (transfer_size > 0) {
- if (s->packet_transfer_size <= 0)
- break;
- len = s->cd_sector_size - s->io_buffer_index;
- if (len <= 0) {
- /* transfert next data */
- cd_read_sector(s->bs, s->lba, s->io_buffer, s->cd_sector_size);
- s->lba++;
- s->io_buffer_index = 0;
- len = s->cd_sector_size;
- }
- if (len > transfer_size)
- len = transfer_size;
- cpu_physical_memory_write(phys_addr,
- s->io_buffer + s->io_buffer_index, len);
- s->packet_transfer_size -= len;
- s->io_buffer_index += len;
- transfer_size -= len;
- phys_addr += len;
- }
- if (s->packet_transfer_size <= 0) {
- s->status = READY_STAT;
- s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD;
-#ifdef DEBUG_IDE_ATAPI
- printf("dma status=0x%x\n", s->status);
-#endif
- return 0;
- }
- return transfer_size1 - transfer_size;
-}
-
-/* start a CD-CDROM read command with DMA */
-/* XXX: test if DMA is available */
-static void ide_atapi_cmd_read_dma(IDEState *s, int lba, int nb_sectors,
- int sector_size)
-{
- s->lba = lba;
- s->packet_transfer_size = nb_sectors * sector_size;
- s->io_buffer_index = sector_size;
- s->cd_sector_size = sector_size;
-
- s->status = READY_STAT | DRQ_STAT;
- ide_dma_start(s, ide_atapi_cmd_read_dma_cb);
-}
-
-static void ide_atapi_cmd_read(IDEState *s, int lba, int nb_sectors,
- int sector_size)
-{
-#ifdef DEBUG_IDE_ATAPI
- printf("read: LBA=%d nb_sectors=%d\n", lba, nb_sectors);
-#endif
- if (s->atapi_dma) {
- ide_atapi_cmd_read_dma(s, lba, nb_sectors, sector_size);
- } else {
- ide_atapi_cmd_read_pio(s, lba, nb_sectors, sector_size);
- }
-}
-
-/* same toc as bochs. Return -1 if error or the toc length */
-/* XXX: check this */
-static int cdrom_read_toc(IDEState *s, uint8_t *buf, int msf, int start_track)
-{
- uint8_t *q;
- int nb_sectors, len;
-
- if (start_track > 1 && start_track != 0xaa)
- return -1;
- q = buf + 2;
- *q++ = 1; /* first session */
- *q++ = 1; /* last session */
- if (start_track <= 1) {
- *q++ = 0; /* reserved */
- *q++ = 0x14; /* ADR, control */
- *q++ = 1; /* track number */
- *q++ = 0; /* reserved */
- if (msf) {
- *q++ = 0; /* reserved */
- *q++ = 0; /* minute */
- *q++ = 2; /* second */
- *q++ = 0; /* frame */
- } else {
- /* sector 0 */
- cpu_to_ube32(q, 0);
- q += 4;
- }
- }
- /* lead out track */
- *q++ = 0; /* reserved */
- *q++ = 0x16; /* ADR, control */
- *q++ = 0xaa; /* track number */
- *q++ = 0; /* reserved */
- nb_sectors = s->nb_sectors >> 2;
- if (msf) {
- *q++ = 0; /* reserved */
- lba_to_msf(q, nb_sectors);
- q += 3;
- } else {
- cpu_to_ube32(q, nb_sectors);
- q += 4;
- }
- len = q - buf;
- cpu_to_ube16(buf, len - 2);
- return len;
-}
-
-/* mostly same info as PearPc */
-static int cdrom_read_toc_raw(IDEState *s, uint8_t *buf, int msf,
- int session_num)
-{
- uint8_t *q;
- int nb_sectors, len;
-
- q = buf + 2;
- *q++ = 1; /* first session */
- *q++ = 1; /* last session */
-
- *q++ = 1; /* session number */
- *q++ = 0x14; /* data track */
- *q++ = 0; /* track number */
- *q++ = 0xa0; /* lead-in */
- *q++ = 0; /* min */
- *q++ = 0; /* sec */
- *q++ = 0; /* frame */
- *q++ = 0;
- *q++ = 1; /* first track */
- *q++ = 0x00; /* disk type */
- *q++ = 0x00;
-
- *q++ = 1; /* session number */
- *q++ = 0x14; /* data track */
- *q++ = 0; /* track number */
- *q++ = 0xa1;
- *q++ = 0; /* min */
- *q++ = 0; /* sec */
- *q++ = 0; /* frame */
- *q++ = 0;
- *q++ = 1; /* last track */
- *q++ = 0x00;
- *q++ = 0x00;
-
- *q++ = 1; /* session number */
- *q++ = 0x14; /* data track */
- *q++ = 0; /* track number */
- *q++ = 0xa2; /* lead-out */
- *q++ = 0; /* min */
- *q++ = 0; /* sec */
- *q++ = 0; /* frame */
- nb_sectors = s->nb_sectors >> 2;
- if (msf) {
- *q++ = 0; /* reserved */
- lba_to_msf(q, nb_sectors);
- q += 3;
- } else {
- cpu_to_ube32(q, nb_sectors);
- q += 4;
- }
-
- *q++ = 1; /* session number */
- *q++ = 0x14; /* ADR, control */
- *q++ = 0; /* track number */
- *q++ = 1; /* point */
- *q++ = 0; /* min */
- *q++ = 0; /* sec */
- *q++ = 0; /* frame */
- *q++ = 0;
- *q++ = 0;
- *q++ = 0;
- *q++ = 0;
-
- len = q - buf;
- cpu_to_ube16(buf, len - 2);
- return len;
-}
-
-static void ide_atapi_cmd(IDEState *s)
-{
- const uint8_t *packet;
- uint8_t *buf;
- int max_len;
-
- packet = s->io_buffer;
- buf = s->io_buffer;
-#ifdef DEBUG_IDE_ATAPI
- {
- int i;
- printf("ATAPI limit=0x%x packet:", s->lcyl | (s->hcyl << 8));
- for(i = 0; i < ATAPI_PACKET_SIZE; i++) {
- printf(" %02x", packet[i]);
- }
- printf("\n");
- }
-#endif
- switch(s->io_buffer[0]) {
- case GPCMD_TEST_UNIT_READY:
- if (bdrv_is_inserted(s->bs)) {
- ide_atapi_cmd_ok(s);
- } else {
- ide_atapi_cmd_error(s, SENSE_NOT_READY,
- ASC_MEDIUM_NOT_PRESENT);
- }
- break;
- case GPCMD_MODE_SENSE_10:
- {
- int action, code;
- max_len = ube16_to_cpu(packet + 7);
- action = packet[2] >> 6;
- code = packet[2] & 0x3f;
- switch(action) {
- case 0: /* current values */
- switch(code) {
- case 0x01: /* error recovery */
- cpu_to_ube16(&buf[0], 16 + 6);
- buf[2] = 0x70;
- buf[3] = 0;
- buf[4] = 0;
- buf[5] = 0;
- buf[6] = 0;
- buf[7] = 0;
-
- buf[8] = 0x01;
- buf[9] = 0x06;
- buf[10] = 0x00;
- buf[11] = 0x05;
- buf[12] = 0x00;
- buf[13] = 0x00;
- buf[14] = 0x00;
- buf[15] = 0x00;
- ide_atapi_cmd_reply(s, 16, max_len);
- break;
- case 0x2a:
- cpu_to_ube16(&buf[0], 28 + 6);
- buf[2] = 0x70;
- buf[3] = 0;
- buf[4] = 0;
- buf[5] = 0;
- buf[6] = 0;
- buf[7] = 0;
-
- buf[8] = 0x2a;
- buf[9] = 0x12;
- buf[10] = 0x00;
- buf[11] = 0x00;
-
- buf[12] = 0x70;
- buf[13] = 3 << 5;
- buf[14] = (1 << 0) | (1 << 3) | (1 << 5);
- if (bdrv_is_locked(s->bs))
- buf[6] |= 1 << 1;
- buf[15] = 0x00;
- cpu_to_ube16(&buf[16], 706);
- buf[18] = 0;
- buf[19] = 2;
- cpu_to_ube16(&buf[20], 512);
- cpu_to_ube16(&buf[22], 706);
- buf[24] = 0;
- buf[25] = 0;
- buf[26] = 0;
- buf[27] = 0;
- ide_atapi_cmd_reply(s, 28, max_len);
- break;
- default:
- goto error_cmd;
- }
- break;
- case 1: /* changeable values */
- goto error_cmd;
- case 2: /* default values */
- goto error_cmd;
- default:
- case 3: /* saved values */
- ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
- ASC_SAVING_PARAMETERS_NOT_SUPPORTED);
- break;
- }
- }
- break;
- case GPCMD_REQUEST_SENSE:
- max_len = packet[4];
- memset(buf, 0, 18);
- buf[0] = 0x70 | (1 << 7);
- buf[2] = s->sense_key;
- buf[7] = 10;
- buf[12] = s->asc;
- ide_atapi_cmd_reply(s, 18, max_len);
- break;
- case GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL:
- if (bdrv_is_inserted(s->bs)) {
- bdrv_set_locked(s->bs, packet[4] & 1);
- ide_atapi_cmd_ok(s);
- } else {
- ide_atapi_cmd_error(s, SENSE_NOT_READY,
- ASC_MEDIUM_NOT_PRESENT);
- }
- break;
- case GPCMD_READ_10:
- case GPCMD_READ_12:
- {
- int nb_sectors, lba;
-
- if (!bdrv_is_inserted(s->bs)) {
- ide_atapi_cmd_error(s, SENSE_NOT_READY,
- ASC_MEDIUM_NOT_PRESENT);
- break;
- }
- if (packet[0] == GPCMD_READ_10)
- nb_sectors = ube16_to_cpu(packet + 7);
- else
- nb_sectors = ube32_to_cpu(packet + 6);
- lba = ube32_to_cpu(packet + 2);
- if (nb_sectors == 0) {
- ide_atapi_cmd_ok(s);
- break;
- }
- if (((int64_t)(lba + nb_sectors) << 2) > s->nb_sectors) {
- ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
- ASC_LOGICAL_BLOCK_OOR);
- break;
- }
- ide_atapi_cmd_read(s, lba, nb_sectors, 2048);
- }
- break;
- case GPCMD_READ_CD:
- {
- int nb_sectors, lba, transfer_request;
-
- if (!bdrv_is_inserted(s->bs)) {
- ide_atapi_cmd_error(s, SENSE_NOT_READY,
- ASC_MEDIUM_NOT_PRESENT);
- break;
- }
- nb_sectors = (packet[6] << 16) | (packet[7] << 8) | packet[8];
- lba = ube32_to_cpu(packet + 2);
- if (nb_sectors == 0) {
- ide_atapi_cmd_ok(s);
- break;
- }
- if (((int64_t)(lba + nb_sectors) << 2) > s->nb_sectors) {
- ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
- ASC_LOGICAL_BLOCK_OOR);
- break;
- }
- transfer_request = packet[9];
- switch(transfer_request & 0xf8) {
- case 0x00:
- /* nothing */
- ide_atapi_cmd_ok(s);
- break;
- case 0x10:
- /* normal read */
- ide_atapi_cmd_read(s, lba, nb_sectors, 2048);
- break;
- case 0xf8:
- /* read all data */
- ide_atapi_cmd_read(s, lba, nb_sectors, 2352);
- break;
- default:
- ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
- ASC_INV_FIELD_IN_CMD_PACKET);
- break;
- }
- }
- break;
- case GPCMD_SEEK:
- {
- int lba;
- if (!bdrv_is_inserted(s->bs)) {
- ide_atapi_cmd_error(s, SENSE_NOT_READY,
- ASC_MEDIUM_NOT_PRESENT);
- break;
- }
- lba = ube32_to_cpu(packet + 2);
- if (((int64_t)lba << 2) > s->nb_sectors) {
- ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
- ASC_LOGICAL_BLOCK_OOR);
- break;
- }
- ide_atapi_cmd_ok(s);
- }
- break;
- case GPCMD_START_STOP_UNIT:
- {
- int start, eject;
- start = packet[4] & 1;
- eject = (packet[4] >> 1) & 1;
-
- if (eject && !start) {
- /* eject the disk */
- bdrv_close(s->bs);
- }
- ide_atapi_cmd_ok(s);
- }
- break;
- case GPCMD_MECHANISM_STATUS:
- {
- max_len = ube16_to_cpu(packet + 8);
- cpu_to_ube16(buf, 0);
- /* no current LBA */
- buf[2] = 0;
- buf[3] = 0;
- buf[4] = 0;
- buf[5] = 1;
- cpu_to_ube16(buf + 6, 0);
- ide_atapi_cmd_reply(s, 8, max_len);
- }
- break;
- case GPCMD_READ_TOC_PMA_ATIP:
- {
- int format, msf, start_track, len;
-
- if (!bdrv_is_inserted(s->bs)) {
- ide_atapi_cmd_error(s, SENSE_NOT_READY,
- ASC_MEDIUM_NOT_PRESENT);
- break;
- }
- max_len = ube16_to_cpu(packet + 7);
- format = packet[9] >> 6;
- msf = (packet[1] >> 1) & 1;
- start_track = packet[6];
- switch(format) {
- case 0:
- len = cdrom_read_toc(s, buf, msf, start_track);
- if (len < 0)
- goto error_cmd;
- ide_atapi_cmd_reply(s, len, max_len);
- break;
- case 1:
- /* multi session : only a single session defined */
- memset(buf, 0, 12);
- buf[1] = 0x0a;
- buf[2] = 0x01;
- buf[3] = 0x01;
- ide_atapi_cmd_reply(s, 12, max_len);
- break;
- case 2:
- len = cdrom_read_toc_raw(s, buf, msf, start_track);
- if (len < 0)
- goto error_cmd;
- ide_atapi_cmd_reply(s, len, max_len);
- break;
- default:
- error_cmd:
- ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
- ASC_INV_FIELD_IN_CMD_PACKET);
- break;
- }
- }
- break;
- case GPCMD_READ_CDVD_CAPACITY:
- if (!bdrv_is_inserted(s->bs)) {
- ide_atapi_cmd_error(s, SENSE_NOT_READY,
- ASC_MEDIUM_NOT_PRESENT);
- break;
- }
- /* NOTE: it is really the number of sectors minus 1 */
- cpu_to_ube32(buf, (s->nb_sectors >> 2) - 1);
- cpu_to_ube32(buf + 4, 2048);
- ide_atapi_cmd_reply(s, 8, 8);
- break;
- case GPCMD_INQUIRY:
- max_len = packet[4];
- buf[0] = 0x05; /* CD-ROM */
- buf[1] = 0x80; /* removable */
- buf[2] = 0x00; /* ISO */
- buf[3] = 0x21; /* ATAPI-2 (XXX: put ATAPI-4 ?) */
- buf[4] = 31; /* additionnal length */
- buf[5] = 0; /* reserved */
- buf[6] = 0; /* reserved */
- buf[7] = 0; /* reserved */
- padstr8(buf + 8, 8, "QEMU");
- padstr8(buf + 16, 16, "QEMU CD-ROM");
- padstr8(buf + 32, 4, QEMU_VERSION);
- ide_atapi_cmd_reply(s, 36, max_len);
- break;
- default:
- ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
- ASC_ILLEGAL_OPCODE);
- break;
- }
-}
-
-/* called when the inserted state of the media has changed */
-static void cdrom_change_cb(void *opaque)
-{
- IDEState *s = opaque;
- int64_t nb_sectors;
-
- /* XXX: send interrupt too */
- bdrv_get_geometry(s->bs, &nb_sectors);
- s->nb_sectors = nb_sectors;
-}
-
-static void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val)
-{
- IDEState *ide_if = opaque;
- IDEState *s;
- int unit, n;
-
-#ifdef DEBUG_IDE
- printf("IDE: write addr=0x%x val=0x%02x\n", addr, val);
-#endif
- addr &= 7;
- switch(addr) {
- case 0:
- break;
- case 1:
- /* NOTE: data is written to the two drives */
- ide_if[0].feature = val;
- ide_if[1].feature = val;
- break;
- case 2:
- if (val == 0)
- val = 256;
- ide_if[0].nsector = val;
- ide_if[1].nsector = val;
- break;
- case 3:
- ide_if[0].sector = val;
- ide_if[1].sector = val;
- break;
- case 4:
- ide_if[0].lcyl = val;
- ide_if[1].lcyl = val;
- break;
- case 5:
- ide_if[0].hcyl = val;
- ide_if[1].hcyl = val;
- break;
- case 6:
- ide_if[0].select = (val & ~0x10) | 0xa0;
- ide_if[1].select = (val | 0x10) | 0xa0;
- /* select drive */
- unit = (val >> 4) & 1;
- s = ide_if + unit;
- ide_if->cur_drive = s;
- break;
- default:
- case 7:
- /* command */
-#if defined(DEBUG_IDE)
- printf("ide: CMD=%02x\n", val);
-#endif
- s = ide_if->cur_drive;
- /* ignore commands to non existant slave */
- if (s != ide_if && !s->bs)
- break;
- switch(val) {
- case WIN_IDENTIFY:
- if (s->bs && !s->is_cdrom) {
- ide_identify(s);
- s->status = READY_STAT | SEEK_STAT;
- ide_transfer_start(s, s->io_buffer, 512, ide_transfer_stop);
- } else {
- if (s->is_cdrom) {
- ide_set_signature(s);
- }
- ide_abort_command(s);
- }
- ide_set_irq(s);
- break;
- case WIN_SPECIFY:
- case WIN_RECAL:
- s->error = 0;
- s->status = READY_STAT | SEEK_STAT;
- ide_set_irq(s);
- break;
- case WIN_SETMULT:
- if (s->nsector > MAX_MULT_SECTORS ||
- s->nsector == 0 ||
- (s->nsector & (s->nsector - 1)) != 0) {
- ide_abort_command(s);
- } else {
- s->mult_sectors = s->nsector;
- s->status = READY_STAT;
- }
- ide_set_irq(s);
- break;
- case WIN_VERIFY:
- case WIN_VERIFY_ONCE:
- /* do sector number check ? */
- s->status = READY_STAT;
- ide_set_irq(s);
- break;
- case WIN_READ:
- case WIN_READ_ONCE:
- if (!s->bs)
- goto abort_cmd;
- s->req_nb_sectors = 1;
- ide_sector_read(s);
- break;
- case WIN_WRITE:
- case WIN_WRITE_ONCE:
- s->error = 0;
- s->status = SEEK_STAT | READY_STAT;
- s->req_nb_sectors = 1;
- ide_transfer_start(s, s->io_buffer, 512, ide_sector_write);
- break;
- case WIN_MULTREAD:
- if (!s->mult_sectors)
- goto abort_cmd;
- s->req_nb_sectors = s->mult_sectors;
- ide_sector_read(s);
- break;
- case WIN_MULTWRITE:
- if (!s->mult_sectors)
- goto abort_cmd;
- s->error = 0;
- s->status = SEEK_STAT | READY_STAT;
- s->req_nb_sectors = s->mult_sectors;
- n = s->nsector;
- if (n > s->req_nb_sectors)
- n = s->req_nb_sectors;
- ide_transfer_start(s, s->io_buffer, 512 * n, ide_sector_write);
- break;
- case WIN_READDMA:
- case WIN_READDMA_ONCE:
- if (!s->bs)
- goto abort_cmd;
- ide_sector_read_dma(s);
- break;
- case WIN_WRITEDMA:
- case WIN_WRITEDMA_ONCE:
- if (!s->bs)
- goto abort_cmd;
- ide_sector_write_dma(s);
- break;
- case WIN_READ_NATIVE_MAX:
- ide_set_sector(s, s->nb_sectors - 1);
- s->status = READY_STAT;
- ide_set_irq(s);
- break;
- case WIN_CHECKPOWERMODE1:
- s->nsector = 0xff; /* device active or idle */
- s->status = READY_STAT;
- ide_set_irq(s);
- break;
- case WIN_SETFEATURES:
- if (!s->bs)
- goto abort_cmd;
- /* XXX: valid for CDROM ? */
- switch(s->feature) {
- case 0x02: /* write cache enable */
- case 0x03: /* set transfer mode */
- case 0x82: /* write cache disable */
- case 0xaa: /* read look-ahead enable */
- case 0x55: /* read look-ahead disable */
- s->status = READY_STAT | SEEK_STAT;
- ide_set_irq(s);
- break;
- default:
- goto abort_cmd;
- }
- break;
- case WIN_STANDBYNOW1:
- s->status = READY_STAT;
- ide_set_irq(s);
- break;
- /* ATAPI commands */
- case WIN_PIDENTIFY:
- if (s->is_cdrom) {
- ide_atapi_identify(s);
- s->status = READY_STAT;
- ide_transfer_start(s, s->io_buffer, 512, ide_transfer_stop);
- } else {
- ide_abort_command(s);
- }
- ide_set_irq(s);
- break;
- case WIN_SRST:
- if (!s->is_cdrom)
- goto abort_cmd;
- ide_set_signature(s);
- s->status = 0x00; /* NOTE: READY is _not_ set */
- s->error = 0x01;
- break;
- case WIN_PACKETCMD:
- if (!s->is_cdrom)
- goto abort_cmd;
- /* overlapping commands not supported */
- if (s->feature & 0x02)
- goto abort_cmd;
- s->atapi_dma = s->feature & 1;
- s->nsector = 1;
- ide_transfer_start(s, s->io_buffer, ATAPI_PACKET_SIZE,
- ide_atapi_cmd);
- break;
- default:
- abort_cmd:
- ide_abort_command(s);
- ide_set_irq(s);
- break;
- }
- }
-}
-
-static uint32_t ide_ioport_read(void *opaque, uint32_t addr1)
-{
- IDEState *ide_if = opaque;
- IDEState *s = ide_if->cur_drive;
- uint32_t addr;
- int ret;
-
- addr = addr1 & 7;
- switch(addr) {
- case 0:
- ret = 0xff;
- break;
- case 1:
- if (!ide_if[0].bs && !ide_if[1].bs)
- ret = 0;
- else
- ret = s->error;
- break;
- case 2:
- if (!ide_if[0].bs && !ide_if[1].bs)
- ret = 0;
- else
- ret = s->nsector & 0xff;
- break;
- case 3:
- if (!ide_if[0].bs && !ide_if[1].bs)
- ret = 0;
- else
- ret = s->sector;
- break;
- case 4:
- if (!ide_if[0].bs && !ide_if[1].bs)
- ret = 0;
- else
- ret = s->lcyl;
- break;
- case 5:
- if (!ide_if[0].bs && !ide_if[1].bs)
- ret = 0;
- else
- ret = s->hcyl;
- break;
- case 6:
- if (!ide_if[0].bs && !ide_if[1].bs)
- ret = 0;
- else
- ret = s->select;
- break;
- default:
- case 7:
- if ((!ide_if[0].bs && !ide_if[1].bs) ||
- (s != ide_if && !s->bs))
- ret = 0;
- else
- ret = s->status;
-#ifdef TARGET_PPC
- if (s->openpic)
- openpic_set_irq(s->openpic, s->irq, 0);
- else
-#endif
- if (s->irq == 16)
- pci_set_irq(s->pci_dev, 0, 0);
- else
- pic_set_irq(s->irq, 0);
- break;
- }
-#ifdef DEBUG_IDE
- printf("ide: read addr=0x%x val=%02x\n", addr1, ret);
-#endif
- return ret;
-}
-
-static uint32_t ide_status_read(void *opaque, uint32_t addr)
-{
- IDEState *ide_if = opaque;
- IDEState *s = ide_if->cur_drive;
- int ret;
-
- if ((!ide_if[0].bs && !ide_if[1].bs) ||
- (s != ide_if && !s->bs))
- ret = 0;
- else
- ret = s->status;
-#ifdef DEBUG_IDE
- printf("ide: read status addr=0x%x val=%02x\n", addr, ret);
-#endif
- return ret;
-}
-
-static void ide_cmd_write(void *opaque, uint32_t addr, uint32_t val)
-{
- IDEState *ide_if = opaque;
- IDEState *s;
- int i;
-
-#ifdef DEBUG_IDE
- printf("ide: write control addr=0x%x val=%02x\n", addr, val);
-#endif
- /* common for both drives */
- if (!(ide_if[0].cmd & IDE_CMD_RESET) &&
- (val & IDE_CMD_RESET)) {
- /* reset low to high */
- for(i = 0;i < 2; i++) {
- s = &ide_if[i];
- s->status = BUSY_STAT | SEEK_STAT;
- s->error = 0x01;
- }
- } else if ((ide_if[0].cmd & IDE_CMD_RESET) &&
- !(val & IDE_CMD_RESET)) {
- /* high to low */
- for(i = 0;i < 2; i++) {
- s = &ide_if[i];
- if (s->is_cdrom)
- s->status = 0x00; /* NOTE: READY is _not_ set */
- else
- s->status = READY_STAT | SEEK_STAT;
- ide_set_signature(s);
- }
- }
-
- ide_if[0].cmd = val;
- ide_if[1].cmd = val;
-}
-
-static void ide_data_writew(void *opaque, uint32_t addr, uint32_t val)
-{
- IDEState *s = ((IDEState *)opaque)->cur_drive;
- uint8_t *p;
-
- p = s->data_ptr;
- *(uint16_t *)p = le16_to_cpu(val);
- p += 2;
- s->data_ptr = p;
- if (p >= s->data_end)
- s->end_transfer_func(s);
-}
-
-static uint32_t ide_data_readw(void *opaque, uint32_t addr)
-{
- IDEState *s = ((IDEState *)opaque)->cur_drive;
- uint8_t *p;
- int ret;
- p = s->data_ptr;
- ret = cpu_to_le16(*(uint16_t *)p);
- p += 2;
- s->data_ptr = p;
- if (p >= s->data_end)
- s->end_transfer_func(s);
- return ret;
-}
-
-static void ide_data_writel(void *opaque, uint32_t addr, uint32_t val)
-{
- IDEState *s = ((IDEState *)opaque)->cur_drive;
- uint8_t *p;
-
- p = s->data_ptr;
- *(uint32_t *)p = le32_to_cpu(val);
- p += 4;
- s->data_ptr = p;
- if (p >= s->data_end)
- s->end_transfer_func(s);
-}
-
-static uint32_t ide_data_readl(void *opaque, uint32_t addr)
-{
- IDEState *s = ((IDEState *)opaque)->cur_drive;
- uint8_t *p;
- int ret;
-
- p = s->data_ptr;
- ret = cpu_to_le32(*(uint32_t *)p);
- p += 4;
- s->data_ptr = p;
- if (p >= s->data_end)
- s->end_transfer_func(s);
- return ret;
-}
-
-static void ide_dummy_transfer_stop(IDEState *s)
-{
- s->data_ptr = s->io_buffer;
- s->data_end = s->io_buffer;
- s->io_buffer[0] = 0xff;
- s->io_buffer[1] = 0xff;
- s->io_buffer[2] = 0xff;
- s->io_buffer[3] = 0xff;
-}
-
-static void ide_reset(IDEState *s)
-{
- s->mult_sectors = MAX_MULT_SECTORS;
- s->cur_drive = s;
- s->select = 0xa0;
- s->status = READY_STAT;
- ide_set_signature(s);
- /* init the transfer handler so that 0xffff is returned on data
- accesses */
- s->end_transfer_func = ide_dummy_transfer_stop;
- ide_dummy_transfer_stop(s);
-}
-
-struct partition {
- uint8_t boot_ind; /* 0x80 - active */
- uint8_t head; /* starting head */
- uint8_t sector; /* starting sector */
- uint8_t cyl; /* starting cylinder */
- uint8_t sys_ind; /* What partition type */
- uint8_t end_head; /* end head */
- uint8_t end_sector; /* end sector */
- uint8_t end_cyl; /* end cylinder */
- uint32_t start_sect; /* starting sector counting from 0 */
- uint32_t nr_sects; /* nr of sectors in partition */
-} __attribute__((packed));
-
-/* try to guess the IDE geometry from the MSDOS partition table */
-static void ide_guess_geometry(IDEState *s)
-{
- uint8_t buf[512];
- int ret, i;
- struct partition *p;
- uint32_t nr_sects;
-
- if (s->cylinders != 0)
- return;
- ret = bdrv_read(s->bs, 0, buf, 1);
- if (ret < 0)
- return;
- /* test msdos magic */
- if (buf[510] != 0x55 || buf[511] != 0xaa)
- return;
- for(i = 0; i < 4; i++) {
- p = ((struct partition *)(buf + 0x1be)) + i;
- nr_sects = le32_to_cpu(p->nr_sects);
- if (nr_sects && p->end_head) {
- /* We make the assumption that the partition terminates on
- a cylinder boundary */
- s->heads = p->end_head + 1;
- s->sectors = p->end_sector & 63;
- if (s->sectors == 0)
- continue;
- s->cylinders = s->nb_sectors / (s->heads * s->sectors);
- if (s->cylinders < 1 || s->cylinders > 16383)
- continue;
-#if 0
- printf("guessed partition: CHS=%d %d %d\n",
- s->cylinders, s->heads, s->sectors);
-#endif
- }
- }
-}
-
-static void ide_init2(IDEState *ide_state, int irq,
- BlockDriverState *hd0, BlockDriverState *hd1)
-{
- IDEState *s;
- static int drive_serial = 1;
- int i, cylinders, heads, secs;
- int64_t nb_sectors;
-
- for(i = 0; i < 2; i++) {
- s = ide_state + i;
- if (i == 0)
- s->bs = hd0;
- else
- s->bs = hd1;
- if (s->bs) {
- bdrv_get_geometry(s->bs, &nb_sectors);
- s->nb_sectors = nb_sectors;
- /* if a geometry hint is available, use it */
- bdrv_get_geometry_hint(s->bs, &cylinders, &heads, &secs);
- if (cylinders != 0) {
- s->cylinders = cylinders;
- s->heads = heads;
- s->sectors = secs;
- } else {
- ide_guess_geometry(s);
-
- /* if heads > 16, it means that a BIOS LBA
- translation was active, so the default
- hardware geometry is OK */
- if ((s->heads > 16) || (s->cylinders == 0)) {
- /* if no geometry, use a standard physical disk geometry */
- cylinders = nb_sectors / (16 * 63);
- if (cylinders > 16383)
- cylinders = 16383;
- else if (cylinders < 2)
- cylinders = 2;
- s->cylinders = cylinders;
- s->heads = 16;
- s->sectors = 63;
- }
- bdrv_set_geometry_hint(s->bs, s->cylinders, s->heads, s->sectors);
- }
- if (bdrv_get_type_hint(s->bs) == BDRV_TYPE_CDROM) {
- s->is_cdrom = 1;
- bdrv_set_change_cb(s->bs, cdrom_change_cb, s);
- }
- }
- s->drive_serial = drive_serial++;
- s->irq = irq;
- ide_reset(s);
- }
-}
-
-static void ide_init_ioport(IDEState *ide_state, int iobase, int iobase2)
-{
- register_ioport_write(iobase, 8, 1, ide_ioport_write, ide_state);
- register_ioport_read(iobase, 8, 1, ide_ioport_read, ide_state);
- if (iobase2) {
- register_ioport_read(iobase2, 1, 1, ide_status_read, ide_state);
- register_ioport_write(iobase2, 1, 1, ide_cmd_write, ide_state);
- }
-
- /* data ports */
- register_ioport_write(iobase, 2, 2, ide_data_writew, ide_state);
- register_ioport_read(iobase, 2, 2, ide_data_readw, ide_state);
- register_ioport_write(iobase, 4, 4, ide_data_writel, ide_state);
- register_ioport_read(iobase, 4, 4, ide_data_readl, ide_state);
-}
-
-/***********************************************************/
-/* ISA IDE definitions */
-
-void isa_ide_init(int iobase, int iobase2, int irq,
- BlockDriverState *hd0, BlockDriverState *hd1)
-{
- IDEState *ide_state;
-
- ide_state = qemu_mallocz(sizeof(IDEState) * 2);
- if (!ide_state)
- return;
-
- ide_init2(ide_state, irq, hd0, hd1);
- ide_init_ioport(ide_state, iobase, iobase2);
-}
-
-/***********************************************************/
-/* PCI IDE definitions */
-
-static void ide_map(PCIDevice *pci_dev, int region_num,
- uint32_t addr, uint32_t size, int type)
-{
- PCIIDEState *d = (PCIIDEState *)pci_dev;
- IDEState *ide_state;
-
- if (region_num <= 3) {
- ide_state = &d->ide_if[(region_num >> 1) * 2];
- if (region_num & 1) {
- register_ioport_read(addr + 2, 1, 1, ide_status_read, ide_state);
- register_ioport_write(addr + 2, 1, 1, ide_cmd_write, ide_state);
- } else {
- register_ioport_write(addr, 8, 1, ide_ioport_write, ide_state);
- register_ioport_read(addr, 8, 1, ide_ioport_read, ide_state);
-
- /* data ports */
- register_ioport_write(addr, 2, 2, ide_data_writew, ide_state);
- register_ioport_read(addr, 2, 2, ide_data_readw, ide_state);
- register_ioport_write(addr, 4, 4, ide_data_writel, ide_state);
- register_ioport_read(addr, 4, 4, ide_data_readl, ide_state);
- }
- }
-}
-
-static void ide_dma_finish(BMDMAState *bm)
-{
- IDEState *s = bm->ide_if;
-
- bm->status &= ~BM_STATUS_DMAING;
- bm->status |= BM_STATUS_INT;
- bm->dma_cb = NULL;
- bm->ide_if = NULL;
- ide_set_irq(s);
-}
-
-/* XXX: full callback usage to prepare non blocking I/Os support -
- error handling */
-#ifdef DMA_MULTI_THREAD
-static void ide_dma_loop(BMDMAState *bm)
-{
- write(file_pipes[1], &bm, sizeof(bm));
-}
-static void dma_thread_loop(BMDMAState *bm)
-#else
-static void ide_dma_loop(BMDMAState *bm)
-#endif //DMA_MULTI_THREAD
-{
- struct {
- uint32_t addr;
- uint32_t size;
- } prd;
- target_phys_addr_t cur_addr;
- int len, i, len1;
-
- cur_addr = bm->addr;
- /* at most one page to avoid hanging if erroneous parameters */
- for(i = 0; i < 512; i++) {
- cpu_physical_memory_read(cur_addr, (uint8_t *)&prd, 8);
- prd.addr = le32_to_cpu(prd.addr);
- prd.size = le32_to_cpu(prd.size);
-#ifdef DEBUG_IDE
- printf("ide: dma: prd: %08x: addr=0x%08x size=0x%08x\n",
- (int)cur_addr, prd.addr, prd.size);
-#endif
- len = prd.size & 0xfffe;
- if (len == 0)
- len = 0x10000;
- while (len > 0) {
- len1 = bm->dma_cb(bm->ide_if, prd.addr, len);
- if (len1 == 0)
- goto the_end;
- prd.addr += len1;
- len -= len1;
- }
- /* end of transfer */
- if (prd.size & 0x80000000)
- break;
- cur_addr += 8;
- }
- /* end of transfer */
-the_end:
- ide_dma_finish(bm);
-}
-
-static void ide_dma_start(IDEState *s, IDEDMAFunc *dma_cb)
-{
- BMDMAState *bm = s->bmdma;
- if(!bm)
- return;
- bm->ide_if = s;
- bm->dma_cb = dma_cb;
- if (bm->status & BM_STATUS_DMAING) {
- ide_dma_loop(bm);
- }
-}
-
-static uint32_t bmdma_cmd_readb(void *opaque, uint32_t addr)
-{
- BMDMAState *bm = opaque;
- uint32_t val;
- val = bm->cmd;
-#ifdef DEBUG_IDE
- printf("%s: 0x%08x\n", __func__, val);
-#endif
- return val;
-}
-
-static void bmdma_cmd_writeb(void *opaque, uint32_t addr, uint32_t val)
-{
- BMDMAState *bm = opaque;
-#ifdef DEBUG_IDE
- printf("%s: 0x%08x\n", __func__, val);
-#endif
- if (!(val & BM_CMD_START)) {
- /* XXX: do it better */
- bm->status &= ~BM_STATUS_DMAING;
- bm->cmd = val & 0x09;
- } else {
- bm->status |= BM_STATUS_DMAING;
- bm->cmd = val & 0x09;
- /* start dma transfer if possible */
- if (bm->dma_cb)
- ide_dma_loop(bm);
- }
-}
-
-static uint32_t bmdma_status_readb(void *opaque, uint32_t addr)
-{
- BMDMAState *bm = opaque;
- uint32_t val;
- val = bm->status;
-#ifdef DEBUG_IDE
- printf("%s: 0x%08x\n", __func__, val);
-#endif
- return val;
-}
-
-static void bmdma_status_writeb(void *opaque, uint32_t addr, uint32_t val)
-{
- BMDMAState *bm = opaque;
-#ifdef DEBUG_IDE
- printf("%s: 0x%08x\n", __func__, val);
-#endif
- bm->status = (val & 0x60) | (bm->status & 1) | (bm->status & ~val & 0x06);
-}
-
-static uint32_t bmdma_addr_readl(void *opaque, uint32_t addr)
-{
- BMDMAState *bm = opaque;
- uint32_t val;
- val = bm->addr;
-#ifdef DEBUG_IDE
- printf("%s: 0x%08x\n", __func__, val);
-#endif
- return val;
-}
-
-static void bmdma_addr_writel(void *opaque, uint32_t addr, uint32_t val)
-{
- BMDMAState *bm = opaque;
-#ifdef DEBUG_IDE
- printf("%s: 0x%08x\n", __func__, val);
-#endif
- bm->addr = val & ~3;
-}
-
-static void bmdma_map(PCIDevice *pci_dev, int region_num,
- uint32_t addr, uint32_t size, int type)
-{
- PCIIDEState *d = (PCIIDEState *)pci_dev;
- int i;
-
- for(i = 0;i < 2; i++) {
- BMDMAState *bm = &d->bmdma[i];
- d->ide_if[2 * i].bmdma = bm;
- d->ide_if[2 * i + 1].bmdma = bm;
-
- register_ioport_write(addr, 1, 1, bmdma_cmd_writeb, bm);
- register_ioport_read(addr, 1, 1, bmdma_cmd_readb, bm);
-
- register_ioport_write(addr + 2, 1, 1, bmdma_status_writeb, bm);
- register_ioport_read(addr + 2, 1, 1, bmdma_status_readb, bm);
-
- register_ioport_write(addr + 4, 4, 4, bmdma_addr_writel, bm);
- register_ioport_read(addr + 4, 4, 4, bmdma_addr_readl, bm);
- addr += 8;
- }
-}
-
-/* hd_table must contain 4 block drivers */
-void pci_ide_init(PCIBus *bus, BlockDriverState **hd_table)
-{
- PCIIDEState *d;
- uint8_t *pci_conf;
- int i;
-
- d = (PCIIDEState *)pci_register_device(bus, "IDE", sizeof(PCIIDEState),
- -1,
- NULL, NULL);
- pci_conf = d->dev.config;
- pci_conf[0x00] = 0x86; // Intel
- pci_conf[0x01] = 0x80;
- pci_conf[0x02] = 0x00; // fake
- pci_conf[0x03] = 0x01; // fake
- pci_conf[0x0a] = 0x01; // class_sub = PCI_IDE
- pci_conf[0x0b] = 0x01; // class_base = PCI_mass_storage
- pci_conf[0x0e] = 0x80; // header_type = PCI_multifunction, generic
-
- pci_conf[0x2c] = 0x86; // subsys vendor
- pci_conf[0x2d] = 0x80; // subsys vendor
- pci_conf[0x2e] = 0x00; // fake
- pci_conf[0x2f] = 0x01; // fake
-
- pci_register_io_region((PCIDevice *)d, 0, 0x8,
- PCI_ADDRESS_SPACE_IO, ide_map);
- pci_register_io_region((PCIDevice *)d, 1, 0x4,
- PCI_ADDRESS_SPACE_IO, ide_map);
- pci_register_io_region((PCIDevice *)d, 2, 0x8,
- PCI_ADDRESS_SPACE_IO, ide_map);
- pci_register_io_region((PCIDevice *)d, 3, 0x4,
- PCI_ADDRESS_SPACE_IO, ide_map);
- pci_register_io_region((PCIDevice *)d, 4, 0x10,
- PCI_ADDRESS_SPACE_IO, bmdma_map);
-
- pci_conf[0x3d] = 0x01; // interrupt on pin 1
-
- for(i = 0; i < 4; i++)
- d->ide_if[i].pci_dev = (PCIDevice *)d;
- ide_init2(&d->ide_if[0], 16, hd_table[0], hd_table[1]);
- ide_init2(&d->ide_if[2], 16, hd_table[2], hd_table[3]);
-#ifdef DMA_MULTI_THREAD
- dma_create_thread();
-#endif //DMA_MULTI_THREAD
-}
-
-/* hd_table must contain 4 block drivers */
-/* NOTE: for the PIIX3, the IRQs and IOports are hardcoded */
-void pci_piix3_ide_init(PCIBus *bus, BlockDriverState **hd_table)
-{
- PCIIDEState *d;
- uint8_t *pci_conf;
-
- /* register a function 1 of PIIX3 */
- d = (PCIIDEState *)pci_register_device(bus, "PIIX3 IDE",
- sizeof(PCIIDEState),
- ((PCIDevice *)piix3_state)->devfn + 1,
- NULL, NULL);
- pci_conf = d->dev.config;
- pci_conf[0x00] = 0x86; // Intel
- pci_conf[0x01] = 0x80;
- pci_conf[0x02] = 0x10;
- pci_conf[0x03] = 0x70;
- pci_conf[0x0a] = 0x01; // class_sub = PCI_IDE
- pci_conf[0x0b] = 0x01; // class_base = PCI_mass_storage
- pci_conf[0x0e] = 0x00; // header_type
-
- pci_register_io_region((PCIDevice *)d, 4, 0x10,
- PCI_ADDRESS_SPACE_IO, bmdma_map);
-
- ide_init2(&d->ide_if[0], 14, hd_table[0], hd_table[1]);
- ide_init2(&d->ide_if[2], 15, hd_table[2], hd_table[3]);
- ide_init_ioport(&d->ide_if[0], 0x1f0, 0x3f6);
- ide_init_ioport(&d->ide_if[2], 0x170, 0x376);
-#ifdef DMA_MULTI_THREAD
- dma_create_thread();
-#endif //DMA_MULTI_THREAD
-}
-
-/***********************************************************/
-/* MacIO based PowerPC IDE */
-
-/* PowerMac IDE memory IO */
-static void pmac_ide_writeb (void *opaque,
- target_phys_addr_t addr, uint32_t val)
-{
- addr = (addr & 0xFFF) >> 4;
- switch (addr) {
- case 1 ... 7:
- ide_ioport_write(opaque, addr, val);
- break;
- case 8:
- case 22:
- ide_cmd_write(opaque, 0, val);
- break;
- default:
- break;
- }
-}
-
-static uint32_t pmac_ide_readb (void *opaque,target_phys_addr_t addr)
-{
- uint8_t retval;
-
- addr = (addr & 0xFFF) >> 4;
- switch (addr) {
- case 1 ... 7:
- retval = ide_ioport_read(opaque, addr);
- break;
- case 8:
- case 22:
- retval = ide_status_read(opaque, 0);
- break;
- default:
- retval = 0xFF;
- break;
- }
- return retval;
-}
-
-static void pmac_ide_writew (void *opaque,
- target_phys_addr_t addr, uint32_t val)
-{
- addr = (addr & 0xFFF) >> 4;
-#ifdef TARGET_WORDS_BIGENDIAN
- val = bswap16(val);
-#endif
- if (addr == 0) {
- ide_data_writew(opaque, 0, val);
- }
-}
-
-static uint32_t pmac_ide_readw (void *opaque,target_phys_addr_t addr)
-{
- uint16_t retval;
-
- addr = (addr & 0xFFF) >> 4;
- if (addr == 0) {
- retval = ide_data_readw(opaque, 0);
- } else {
- retval = 0xFFFF;
- }
-#ifdef TARGET_WORDS_BIGENDIAN
- retval = bswap16(retval);
-#endif
- return retval;
-}
-
-static void pmac_ide_writel (void *opaque,
- target_phys_addr_t addr, uint32_t val)
-{
- addr = (addr & 0xFFF) >> 4;
-#ifdef TARGET_WORDS_BIGENDIAN
- val = bswap32(val);
-#endif
- if (addr == 0) {
- ide_data_writel(opaque, 0, val);
- }
-}
-
-static uint32_t pmac_ide_readl (void *opaque,target_phys_addr_t addr)
-{
- uint32_t retval;
-
- addr = (addr & 0xFFF) >> 4;
- if (addr == 0) {
- retval = ide_data_readl(opaque, 0);
- } else {
- retval = 0xFFFFFFFF;
- }
-#ifdef TARGET_WORDS_BIGENDIAN
- retval = bswap32(retval);
-#endif
- return retval;
-}
-
-static CPUWriteMemoryFunc *pmac_ide_write[] = {
- pmac_ide_writeb,
- pmac_ide_writew,
- pmac_ide_writel,
-};
-
-static CPUReadMemoryFunc *pmac_ide_read[] = {
- pmac_ide_readb,
- pmac_ide_readw,
- pmac_ide_readl,
-};
-
-/* hd_table must contain 4 block drivers */
-/* PowerMac uses memory mapped registers, not I/O. Return the memory
- I/O index to access the ide. */
-int pmac_ide_init (BlockDriverState **hd_table,
- openpic_t *openpic, int irq)
-{
- IDEState *ide_if;
- int pmac_ide_memory;
-
- ide_if = qemu_mallocz(sizeof(IDEState) * 2);
- ide_init2(&ide_if[0], irq, hd_table[0], hd_table[1]);
- ide_if[0].openpic = openpic;
- ide_if[1].openpic = openpic;
-
- pmac_ide_memory = cpu_register_io_memory(0, pmac_ide_read,
- pmac_ide_write, &ide_if[0]);
- return pmac_ide_memory;
-}
+++ /dev/null
-/*
- * QEMU SPARC iommu emulation
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "vl.h"
-
-/* debug iommu */
-//#define DEBUG_IOMMU
-
-/* The IOMMU registers occupy three pages in IO space. */
-struct iommu_regs {
- /* First page */
- volatile unsigned long control; /* IOMMU control */
- volatile unsigned long base; /* Physical base of iopte page table */
- volatile unsigned long _unused1[3];
- volatile unsigned long tlbflush; /* write only */
- volatile unsigned long pageflush; /* write only */
- volatile unsigned long _unused2[1017];
- /* Second page */
- volatile unsigned long afsr; /* Async-fault status register */
- volatile unsigned long afar; /* Async-fault physical address */
- volatile unsigned long _unused3[2];
- volatile unsigned long sbuscfg0; /* SBUS configuration registers, per-slot */
- volatile unsigned long sbuscfg1;
- volatile unsigned long sbuscfg2;
- volatile unsigned long sbuscfg3;
- volatile unsigned long mfsr; /* Memory-fault status register */
- volatile unsigned long mfar; /* Memory-fault physical address */
- volatile unsigned long _unused4[1014];
- /* Third page */
- volatile unsigned long mid; /* IOMMU module-id */
-};
-
-#define IOMMU_CTRL_IMPL 0xf0000000 /* Implementation */
-#define IOMMU_CTRL_VERS 0x0f000000 /* Version */
-#define IOMMU_CTRL_RNGE 0x0000001c /* Mapping RANGE */
-#define IOMMU_RNGE_16MB 0x00000000 /* 0xff000000 -> 0xffffffff */
-#define IOMMU_RNGE_32MB 0x00000004 /* 0xfe000000 -> 0xffffffff */
-#define IOMMU_RNGE_64MB 0x00000008 /* 0xfc000000 -> 0xffffffff */
-#define IOMMU_RNGE_128MB 0x0000000c /* 0xf8000000 -> 0xffffffff */
-#define IOMMU_RNGE_256MB 0x00000010 /* 0xf0000000 -> 0xffffffff */
-#define IOMMU_RNGE_512MB 0x00000014 /* 0xe0000000 -> 0xffffffff */
-#define IOMMU_RNGE_1GB 0x00000018 /* 0xc0000000 -> 0xffffffff */
-#define IOMMU_RNGE_2GB 0x0000001c /* 0x80000000 -> 0xffffffff */
-#define IOMMU_CTRL_ENAB 0x00000001 /* IOMMU Enable */
-
-#define IOMMU_AFSR_ERR 0x80000000 /* LE, TO, or BE asserted */
-#define IOMMU_AFSR_LE 0x40000000 /* SBUS reports error after transaction */
-#define IOMMU_AFSR_TO 0x20000000 /* Write access took more than 12.8 us. */
-#define IOMMU_AFSR_BE 0x10000000 /* Write access received error acknowledge */
-#define IOMMU_AFSR_SIZE 0x0e000000 /* Size of transaction causing error */
-#define IOMMU_AFSR_S 0x01000000 /* Sparc was in supervisor mode */
-#define IOMMU_AFSR_RESV 0x00f00000 /* Reserver, forced to 0x8 by hardware */
-#define IOMMU_AFSR_ME 0x00080000 /* Multiple errors occurred */
-#define IOMMU_AFSR_RD 0x00040000 /* A read operation was in progress */
-#define IOMMU_AFSR_FAV 0x00020000 /* IOMMU afar has valid contents */
-
-#define IOMMU_SBCFG_SAB30 0x00010000 /* Phys-address bit 30 when bypass enabled */
-#define IOMMU_SBCFG_BA16 0x00000004 /* Slave supports 16 byte bursts */
-#define IOMMU_SBCFG_BA8 0x00000002 /* Slave supports 8 byte bursts */
-#define IOMMU_SBCFG_BYPASS 0x00000001 /* Bypass IOMMU, treat all addresses
- produced by this device as pure
- physical. */
-
-#define IOMMU_MFSR_ERR 0x80000000 /* One or more of PERR1 or PERR0 */
-#define IOMMU_MFSR_S 0x01000000 /* Sparc was in supervisor mode */
-#define IOMMU_MFSR_CPU 0x00800000 /* CPU transaction caused parity error */
-#define IOMMU_MFSR_ME 0x00080000 /* Multiple parity errors occurred */
-#define IOMMU_MFSR_PERR 0x00006000 /* high bit indicates parity error occurred
- on the even word of the access, low bit
- indicated odd word caused the parity error */
-#define IOMMU_MFSR_BM 0x00001000 /* Error occurred while in boot mode */
-#define IOMMU_MFSR_C 0x00000800 /* Address causing error was marked cacheable */
-#define IOMMU_MFSR_RTYP 0x000000f0 /* Memory request transaction type */
-
-#define IOMMU_MID_SBAE 0x001f0000 /* SBus arbitration enable */
-#define IOMMU_MID_SE 0x00100000 /* Enables SCSI/ETHERNET arbitration */
-#define IOMMU_MID_SB3 0x00080000 /* Enable SBUS device 3 arbitration */
-#define IOMMU_MID_SB2 0x00040000 /* Enable SBUS device 2 arbitration */
-#define IOMMU_MID_SB1 0x00020000 /* Enable SBUS device 1 arbitration */
-#define IOMMU_MID_SB0 0x00010000 /* Enable SBUS device 0 arbitration */
-#define IOMMU_MID_MID 0x0000000f /* Module-id, hardcoded to 0x8 */
-
-/* The format of an iopte in the page tables */
-#define IOPTE_PAGE 0x07ffff00 /* Physical page number (PA[30:12]) */
-#define IOPTE_CACHE 0x00000080 /* Cached (in vme IOCACHE or Viking/MXCC) */
-#define IOPTE_WRITE 0x00000004 /* Writeable */
-#define IOPTE_VALID 0x00000002 /* IOPTE is valid */
-#define IOPTE_WAZ 0x00000001 /* Write as zeros */
-
-#if defined(__i386__) || defined(__x86_64__)
-#define PAGE_SHIFT 12
-#elif defined(__ia64__)
-#define PAGE_SHIFT 14
-#endif
-#define PAGE_SIZE (1 << PAGE_SHIFT)
-#define PAGE_MASK (PAGE_SIZE - 1)
-
-typedef struct IOMMUState {
- uint32_t addr;
- uint32_t regs[sizeof(struct iommu_regs)];
- uint32_t iostart;
-} IOMMUState;
-
-static IOMMUState *ps;
-
-static uint32_t iommu_mem_readw(void *opaque, target_phys_addr_t addr)
-{
- IOMMUState *s = opaque;
- uint32_t saddr;
-
- saddr = (addr - s->addr) >> 2;
- switch (saddr) {
- default:
- return s->regs[saddr];
- break;
- }
- return 0;
-}
-
-static void iommu_mem_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
- IOMMUState *s = opaque;
- uint32_t saddr;
-
- saddr = (addr - s->addr) >> 2;
- switch (saddr) {
- case 0:
- switch (val & IOMMU_CTRL_RNGE) {
- case IOMMU_RNGE_16MB:
- s->iostart = 0xff000000;
- break;
- case IOMMU_RNGE_32MB:
- s->iostart = 0xfe000000;
- break;
- case IOMMU_RNGE_64MB:
- s->iostart = 0xfc000000;
- break;
- case IOMMU_RNGE_128MB:
- s->iostart = 0xf8000000;
- break;
- case IOMMU_RNGE_256MB:
- s->iostart = 0xf0000000;
- break;
- case IOMMU_RNGE_512MB:
- s->iostart = 0xe0000000;
- break;
- case IOMMU_RNGE_1GB:
- s->iostart = 0xc0000000;
- break;
- default:
- case IOMMU_RNGE_2GB:
- s->iostart = 0x80000000;
- break;
- }
- /* Fall through */
- default:
- s->regs[saddr] = val;
- break;
- }
-}
-
-static CPUReadMemoryFunc *iommu_mem_read[3] = {
- iommu_mem_readw,
- iommu_mem_readw,
- iommu_mem_readw,
-};
-
-static CPUWriteMemoryFunc *iommu_mem_write[3] = {
- iommu_mem_writew,
- iommu_mem_writew,
- iommu_mem_writew,
-};
-
-uint32_t iommu_translate(uint32_t addr)
-{
- uint32_t *iopte = (void *)(ps->regs[1] << 4), pa;
-
- iopte += ((addr - ps->iostart) >> PAGE_SHIFT);
- cpu_physical_memory_rw((uint32_t)iopte, (void *) &pa, 4, 0);
- bswap32s(&pa);
- pa = (pa & IOPTE_PAGE) << 4; /* Loose higher bits of 36 */
- return pa + (addr & PAGE_MASK);
-}
-
-void iommu_init(uint32_t addr)
-{
- IOMMUState *s;
- int iommu_io_memory;
-
- s = qemu_mallocz(sizeof(IOMMUState));
- if (!s)
- return;
-
- s->addr = addr;
-
- iommu_io_memory = cpu_register_io_memory(0, iommu_mem_read, iommu_mem_write, s);
- cpu_register_physical_memory(addr, sizeof(struct iommu_regs),
- iommu_io_memory);
-
- ps = s;
-}
-
+++ /dev/null
-/*
- * QEMU Lance emulation
- *
- * Copyright (c) 2003-2004 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "vl.h"
-
-/* debug LANCE card */
-//#define DEBUG_LANCE
-
-#ifndef LANCE_LOG_TX_BUFFERS
-#define LANCE_LOG_TX_BUFFERS 4
-#define LANCE_LOG_RX_BUFFERS 4
-#endif
-
-#define CRC_POLYNOMIAL_BE 0x04c11db7UL /* Ethernet CRC, big endian */
-#define CRC_POLYNOMIAL_LE 0xedb88320UL /* Ethernet CRC, little endian */
-
-
-#define LE_CSR0 0
-#define LE_CSR1 1
-#define LE_CSR2 2
-#define LE_CSR3 3
-#define LE_MAXREG (LE_CSR3 + 1)
-
-#define LE_RDP 0
-#define LE_RAP 1
-
-#define LE_MO_PROM 0x8000 /* Enable promiscuous mode */
-
-#define LE_C0_ERR 0x8000 /* Error: set if BAB, SQE, MISS or ME is set */
-#define LE_C0_BABL 0x4000 /* BAB: Babble: tx timeout. */
-#define LE_C0_CERR 0x2000 /* SQE: Signal quality error */
-#define LE_C0_MISS 0x1000 /* MISS: Missed a packet */
-#define LE_C0_MERR 0x0800 /* ME: Memory error */
-#define LE_C0_RINT 0x0400 /* Received interrupt */
-#define LE_C0_TINT 0x0200 /* Transmitter Interrupt */
-#define LE_C0_IDON 0x0100 /* IFIN: Init finished. */
-#define LE_C0_INTR 0x0080 /* Interrupt or error */
-#define LE_C0_INEA 0x0040 /* Interrupt enable */
-#define LE_C0_RXON 0x0020 /* Receiver on */
-#define LE_C0_TXON 0x0010 /* Transmitter on */
-#define LE_C0_TDMD 0x0008 /* Transmitter demand */
-#define LE_C0_STOP 0x0004 /* Stop the card */
-#define LE_C0_STRT 0x0002 /* Start the card */
-#define LE_C0_INIT 0x0001 /* Init the card */
-
-#define LE_C3_BSWP 0x4 /* SWAP */
-#define LE_C3_ACON 0x2 /* ALE Control */
-#define LE_C3_BCON 0x1 /* Byte control */
-
-/* Receive message descriptor 1 */
-#define LE_R1_OWN 0x80 /* Who owns the entry */
-#define LE_R1_ERR 0x40 /* Error: if FRA, OFL, CRC or BUF is set */
-#define LE_R1_FRA 0x20 /* FRA: Frame error */
-#define LE_R1_OFL 0x10 /* OFL: Frame overflow */
-#define LE_R1_CRC 0x08 /* CRC error */
-#define LE_R1_BUF 0x04 /* BUF: Buffer error */
-#define LE_R1_SOP 0x02 /* Start of packet */
-#define LE_R1_EOP 0x01 /* End of packet */
-#define LE_R1_POK 0x03 /* Packet is complete: SOP + EOP */
-
-#define LE_T1_OWN 0x80 /* Lance owns the packet */
-#define LE_T1_ERR 0x40 /* Error summary */
-#define LE_T1_EMORE 0x10 /* Error: more than one retry needed */
-#define LE_T1_EONE 0x08 /* Error: one retry needed */
-#define LE_T1_EDEF 0x04 /* Error: deferred */
-#define LE_T1_SOP 0x02 /* Start of packet */
-#define LE_T1_EOP 0x01 /* End of packet */
-#define LE_T1_POK 0x03 /* Packet is complete: SOP + EOP */
-
-#define LE_T3_BUF 0x8000 /* Buffer error */
-#define LE_T3_UFL 0x4000 /* Error underflow */
-#define LE_T3_LCOL 0x1000 /* Error late collision */
-#define LE_T3_CLOS 0x0800 /* Error carrier loss */
-#define LE_T3_RTY 0x0400 /* Error retry */
-#define LE_T3_TDR 0x03ff /* Time Domain Reflectometry counter */
-
-#define TX_RING_SIZE (1 << (LANCE_LOG_TX_BUFFERS))
-#define TX_RING_MOD_MASK (TX_RING_SIZE - 1)
-#define TX_RING_LEN_BITS ((LANCE_LOG_TX_BUFFERS) << 29)
-
-#define RX_RING_SIZE (1 << (LANCE_LOG_RX_BUFFERS))
-#define RX_RING_MOD_MASK (RX_RING_SIZE - 1)
-#define RX_RING_LEN_BITS ((LANCE_LOG_RX_BUFFERS) << 29)
-
-#define PKT_BUF_SZ 1544
-#define RX_BUFF_SIZE PKT_BUF_SZ
-#define TX_BUFF_SIZE PKT_BUF_SZ
-
-struct lance_rx_desc {
- unsigned short rmd0; /* low address of packet */
- unsigned char rmd1_bits; /* descriptor bits */
- unsigned char rmd1_hadr; /* high address of packet */
- short length; /* This length is 2s complement (negative)!
- * Buffer length
- */
- unsigned short mblength; /* This is the actual number of bytes received */
-};
-
-struct lance_tx_desc {
- unsigned short tmd0; /* low address of packet */
- unsigned char tmd1_bits; /* descriptor bits */
- unsigned char tmd1_hadr; /* high address of packet */
- short length; /* Length is 2s complement (negative)! */
- unsigned short misc;
-};
-
-/* The LANCE initialization block, described in databook. */
-/* On the Sparc, this block should be on a DMA region */
-struct lance_init_block {
- unsigned short mode; /* Pre-set mode (reg. 15) */
- unsigned char phys_addr[6]; /* Physical ethernet address */
- unsigned filter[2]; /* Multicast filter. */
-
- /* Receive and transmit ring base, along with extra bits. */
- unsigned short rx_ptr; /* receive descriptor addr */
- unsigned short rx_len; /* receive len and high addr */
- unsigned short tx_ptr; /* transmit descriptor addr */
- unsigned short tx_len; /* transmit len and high addr */
-
- /* The Tx and Rx ring entries must aligned on 8-byte boundaries. */
- struct lance_rx_desc brx_ring[RX_RING_SIZE];
- struct lance_tx_desc btx_ring[TX_RING_SIZE];
-
- char tx_buf [TX_RING_SIZE][TX_BUFF_SIZE];
- char pad[2]; /* align rx_buf for copy_and_sum(). */
- char rx_buf [RX_RING_SIZE][RX_BUFF_SIZE];
-};
-
-#define LEDMA_REGS 4
-#if 0
-/* Structure to describe the current status of DMA registers on the Sparc */
-struct sparc_dma_registers {
- uint32_t cond_reg; /* DMA condition register */
- uint32_t st_addr; /* Start address of this transfer */
- uint32_t cnt; /* How many bytes to transfer */
- uint32_t dma_test; /* DMA test register */
-};
-#endif
-
-typedef struct LEDMAState {
- uint32_t addr;
- uint32_t regs[LEDMA_REGS];
-} LEDMAState;
-
-typedef struct LANCEState {
- uint32_t paddr;
- NetDriverState *nd;
- uint32_t leptr;
- uint16_t addr;
- uint16_t regs[LE_MAXREG];
- uint8_t phys[6]; /* mac address */
- int irq;
- LEDMAState *ledma;
-} LANCEState;
-
-static unsigned int rxptr, txptr;
-
-static void lance_send(void *opaque);
-
-static void lance_reset(LANCEState *s)
-{
- memcpy(s->phys, s->nd->macaddr, 6);
- rxptr = 0;
- txptr = 0;
- s->regs[LE_CSR0] = LE_C0_STOP;
-}
-
-static uint32_t lance_mem_readw(void *opaque, target_phys_addr_t addr)
-{
- LANCEState *s = opaque;
- uint32_t saddr;
-
- saddr = addr - s->paddr;
- switch (saddr >> 1) {
- case LE_RDP:
- return s->regs[s->addr];
- case LE_RAP:
- return s->addr;
- default:
- break;
- }
- return 0;
-}
-
-static void lance_mem_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
- LANCEState *s = opaque;
- uint32_t saddr;
- uint16_t reg;
-
- saddr = addr - s->paddr;
- switch (saddr >> 1) {
- case LE_RDP:
- switch(s->addr) {
- case LE_CSR0:
- if (val & LE_C0_STOP) {
- s->regs[LE_CSR0] = LE_C0_STOP;
- break;
- }
-
- reg = s->regs[LE_CSR0];
-
- // 1 = clear for some bits
- reg &= ~(val & 0x7f00);
-
- // generated bits
- reg &= ~(LE_C0_ERR | LE_C0_INTR);
- if (reg & 0x7100)
- reg |= LE_C0_ERR;
- if (reg & 0x7f00)
- reg |= LE_C0_INTR;
-
- // direct bit
- reg &= ~LE_C0_INEA;
- reg |= val & LE_C0_INEA;
-
- // exclusive bits
- if (val & LE_C0_INIT) {
- reg |= LE_C0_IDON | LE_C0_INIT;
- reg &= ~LE_C0_STOP;
- }
- else if (val & LE_C0_STRT) {
- reg |= LE_C0_STRT | LE_C0_RXON | LE_C0_TXON;
- reg &= ~LE_C0_STOP;
- }
-
- s->regs[LE_CSR0] = reg;
-
- // trigger bits
- //if (val & LE_C0_TDMD)
-
- if ((s->regs[LE_CSR0] & LE_C0_INTR) && (s->regs[LE_CSR0] & LE_C0_INEA))
- pic_set_irq(s->irq, 1);
- break;
- case LE_CSR1:
- s->leptr = (s->leptr & 0xffff0000) | (val & 0xffff);
- s->regs[s->addr] = val;
- break;
- case LE_CSR2:
- s->leptr = (s->leptr & 0xffff) | ((val & 0xffff) << 16);
- s->regs[s->addr] = val;
- break;
- case LE_CSR3:
- s->regs[s->addr] = val;
- break;
- }
- break;
- case LE_RAP:
- if (val < LE_MAXREG)
- s->addr = val;
- break;
- default:
- break;
- }
- lance_send(s);
-}
-
-static CPUReadMemoryFunc *lance_mem_read[3] = {
- lance_mem_readw,
- lance_mem_readw,
- lance_mem_readw,
-};
-
-static CPUWriteMemoryFunc *lance_mem_write[3] = {
- lance_mem_writew,
- lance_mem_writew,
- lance_mem_writew,
-};
-
-
-/* return the max buffer size if the LANCE can receive more data */
-static int lance_can_receive(void *opaque)
-{
- LANCEState *s = opaque;
- void *dmaptr = (void *) (s->leptr + s->ledma->regs[3]);
- struct lance_init_block *ib;
- int i;
- uint16_t temp;
-
- if ((s->regs[LE_CSR0] & LE_C0_STOP) == LE_C0_STOP)
- return 0;
-
- ib = (void *) iommu_translate(dmaptr);
-
- for (i = 0; i < RX_RING_SIZE; i++) {
- cpu_physical_memory_read(&ib->brx_ring[i].rmd1_bits, (void *) &temp, 1);
- temp &= 0xff;
- if (temp == (LE_R1_OWN)) {
-#ifdef DEBUG_LANCE
- fprintf(stderr, "lance: can receive %d\n", RX_BUFF_SIZE);
-#endif
- return RX_BUFF_SIZE;
- }
- }
-#ifdef DEBUG_LANCE
- fprintf(stderr, "lance: cannot receive\n");
-#endif
- return 0;
-}
-
-#define MIN_BUF_SIZE 60
-
-static void lance_receive(void *opaque, const uint8_t *buf, int size)
-{
- LANCEState *s = opaque;
- void *dmaptr = (void *) (s->leptr + s->ledma->regs[3]);
- struct lance_init_block *ib;
- unsigned int i, old_rxptr, j;
- uint16_t temp;
-
- if ((s->regs[LE_CSR0] & LE_C0_STOP) == LE_C0_STOP)
- return;
-
- ib = (void *) iommu_translate(dmaptr);
-
- old_rxptr = rxptr;
- for (i = rxptr; i != ((old_rxptr - 1) & RX_RING_MOD_MASK); i = (i + 1) & RX_RING_MOD_MASK) {
- cpu_physical_memory_read(&ib->brx_ring[i].rmd1_bits, (void *) &temp, 1);
- if (temp == (LE_R1_OWN)) {
- rxptr = (rxptr + 1) & RX_RING_MOD_MASK;
- temp = size;
- bswap16s(&temp);
- cpu_physical_memory_write(&ib->brx_ring[i].mblength, (void *) &temp, 2);
-#if 0
- cpu_physical_memory_write(&ib->rx_buf[i], buf, size);
-#else
- for (j = 0; j < size; j++) {
- cpu_physical_memory_write(((void *)&ib->rx_buf[i]) + j, &buf[j], 1);
- }
-#endif
- temp = LE_R1_POK;
- cpu_physical_memory_write(&ib->brx_ring[i].rmd1_bits, (void *) &temp, 1);
- s->regs[LE_CSR0] |= LE_C0_RINT | LE_C0_INTR;
- if ((s->regs[LE_CSR0] & LE_C0_INTR) && (s->regs[LE_CSR0] & LE_C0_INEA))
- pic_set_irq(s->irq, 1);
-#ifdef DEBUG_LANCE
- fprintf(stderr, "lance: got packet, len %d\n", size);
-#endif
- return;
- }
- }
-}
-
-static void lance_send(void *opaque)
-{
- LANCEState *s = opaque;
- void *dmaptr = (void *) (s->leptr + s->ledma->regs[3]);
- struct lance_init_block *ib;
- unsigned int i, old_txptr, j;
- uint16_t temp;
- char pkt_buf[PKT_BUF_SZ];
-
- if ((s->regs[LE_CSR0] & LE_C0_STOP) == LE_C0_STOP)
- return;
-
- ib = (void *) iommu_translate(dmaptr);
-
- old_txptr = txptr;
- for (i = txptr; i != ((old_txptr - 1) & TX_RING_MOD_MASK); i = (i + 1) & TX_RING_MOD_MASK) {
- cpu_physical_memory_read(&ib->btx_ring[i].tmd1_bits, (void *) &temp, 1);
- if (temp == (LE_T1_POK|LE_T1_OWN)) {
- cpu_physical_memory_read(&ib->btx_ring[i].length, (void *) &temp, 2);
- bswap16s(&temp);
- temp = (~temp) + 1;
-#if 0
- cpu_physical_memory_read(&ib->tx_buf[i], pkt_buf, temp);
-#else
- for (j = 0; j < temp; j++) {
- cpu_physical_memory_read(((void *)&ib->tx_buf[i]) + j, &pkt_buf[j], 1);
- }
-#endif
-
-#ifdef DEBUG_LANCE
- fprintf(stderr, "lance: sending packet, len %d\n", temp);
-#endif
- qemu_send_packet(s->nd, pkt_buf, temp);
- temp = LE_T1_POK;
- cpu_physical_memory_write(&ib->btx_ring[i].tmd1_bits, (void *) &temp, 1);
- txptr = (txptr + 1) & TX_RING_MOD_MASK;
- s->regs[LE_CSR0] |= LE_C0_TINT | LE_C0_INTR;
- }
- }
-}
-
-static uint32_t ledma_mem_readl(void *opaque, target_phys_addr_t addr)
-{
- LEDMAState *s = opaque;
- uint32_t saddr;
-
- saddr = (addr - s->addr) >> 2;
- if (saddr < LEDMA_REGS)
- return s->regs[saddr];
- else
- return 0;
-}
-
-static void ledma_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
- LEDMAState *s = opaque;
- uint32_t saddr;
-
- saddr = (addr - s->addr) >> 2;
- if (saddr < LEDMA_REGS)
- s->regs[saddr] = val;
-}
-
-static CPUReadMemoryFunc *ledma_mem_read[3] = {
- ledma_mem_readl,
- ledma_mem_readl,
- ledma_mem_readl,
-};
-
-static CPUWriteMemoryFunc *ledma_mem_write[3] = {
- ledma_mem_writel,
- ledma_mem_writel,
- ledma_mem_writel,
-};
-
-void lance_init(NetDriverState *nd, int irq, uint32_t leaddr, uint32_t ledaddr)
-{
- LANCEState *s;
- LEDMAState *led;
- int lance_io_memory, ledma_io_memory;
-
- s = qemu_mallocz(sizeof(LANCEState));
- if (!s)
- return;
-
- s->paddr = leaddr;
- s->nd = nd;
- s->irq = irq;
-
- lance_io_memory = cpu_register_io_memory(0, lance_mem_read, lance_mem_write, s);
- cpu_register_physical_memory(leaddr, 8, lance_io_memory);
-
- led = qemu_mallocz(sizeof(LEDMAState));
- if (!led)
- return;
-
- s->ledma = led;
- led->addr = ledaddr;
- ledma_io_memory = cpu_register_io_memory(0, ledma_mem_read, ledma_mem_write, led);
- cpu_register_physical_memory(ledaddr, 16, ledma_io_memory);
-
- lance_reset(s);
- qemu_add_read_packet(nd, lance_can_receive, lance_receive, s);
-}
-
+++ /dev/null
-/*
- * QEMU M48T08 NVRAM emulation for Sparc platform
- *
- * Copyright (c) 2003-2004 Jocelyn Mayer
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "vl.h"
-#include "m48t08.h"
-
-//#define DEBUG_NVRAM
-
-#if defined(DEBUG_NVRAM)
-#define NVRAM_PRINTF(fmt, args...) do { printf(fmt , ##args); } while (0)
-#else
-#define NVRAM_PRINTF(fmt, args...) do { } while (0)
-#endif
-
-#define NVRAM_MAX_MEM 0xfff0
-
-struct m48t08_t {
- /* Hardware parameters */
- int mem_index;
- uint32_t mem_base;
- uint16_t size;
- /* RTC management */
- time_t time_offset;
- time_t stop_time;
- /* NVRAM storage */
- uint8_t lock;
- uint16_t addr;
- uint8_t *buffer;
-};
-
-/* Fake timer functions */
-/* Generic helpers for BCD */
-static inline uint8_t toBCD (uint8_t value)
-{
- return (((value / 10) % 10) << 4) | (value % 10);
-}
-
-static inline uint8_t fromBCD (uint8_t BCD)
-{
- return ((BCD >> 4) * 10) + (BCD & 0x0F);
-}
-
-/* RTC management helpers */
-static void get_time (m48t08_t *NVRAM, struct tm *tm)
-{
- time_t t;
-
- t = time(NULL) + NVRAM->time_offset;
-#ifdef _WIN32
- memcpy(tm,localtime(&t),sizeof(*tm));
-#else
- localtime_r (&t, tm) ;
-#endif
-}
-
-static void set_time (m48t08_t *NVRAM, struct tm *tm)
-{
- time_t now, new_time;
-
- new_time = mktime(tm);
- now = time(NULL);
- NVRAM->time_offset = new_time - now;
-}
-
-/* Direct access to NVRAM */
-void m48t08_write (m48t08_t *NVRAM, uint32_t val)
-{
- struct tm tm;
- int tmp;
-
- if (NVRAM->addr > NVRAM_MAX_MEM && NVRAM->addr < 0x2000)
- NVRAM_PRINTF("%s: 0x%08x => 0x%08x\n", __func__, NVRAM->addr, val);
- switch (NVRAM->addr) {
- case 0x1FF8:
- /* control */
- NVRAM->buffer[0x1FF8] = (val & ~0xA0) | 0x90;
- break;
- case 0x1FF9:
- /* seconds (BCD) */
- tmp = fromBCD(val & 0x7F);
- if (tmp >= 0 && tmp <= 59) {
- get_time(NVRAM, &tm);
- tm.tm_sec = tmp;
- set_time(NVRAM, &tm);
- }
- if ((val & 0x80) ^ (NVRAM->buffer[0x1FF9] & 0x80)) {
- if (val & 0x80) {
- NVRAM->stop_time = time(NULL);
- } else {
- NVRAM->time_offset += NVRAM->stop_time - time(NULL);
- NVRAM->stop_time = 0;
- }
- }
- NVRAM->buffer[0x1FF9] = val & 0x80;
- break;
- case 0x1FFA:
- /* minutes (BCD) */
- tmp = fromBCD(val & 0x7F);
- if (tmp >= 0 && tmp <= 59) {
- get_time(NVRAM, &tm);
- tm.tm_min = tmp;
- set_time(NVRAM, &tm);
- }
- break;
- case 0x1FFB:
- /* hours (BCD) */
- tmp = fromBCD(val & 0x3F);
- if (tmp >= 0 && tmp <= 23) {
- get_time(NVRAM, &tm);
- tm.tm_hour = tmp;
- set_time(NVRAM, &tm);
- }
- break;
- case 0x1FFC:
- /* day of the week / century */
- tmp = fromBCD(val & 0x07);
- get_time(NVRAM, &tm);
- tm.tm_wday = tmp;
- set_time(NVRAM, &tm);
- NVRAM->buffer[0x1FFC] = val & 0x40;
- break;
- case 0x1FFD:
- /* date */
- tmp = fromBCD(val & 0x1F);
- if (tmp != 0) {
- get_time(NVRAM, &tm);
- tm.tm_mday = tmp;
- set_time(NVRAM, &tm);
- }
- break;
- case 0x1FFE:
- /* month */
- tmp = fromBCD(val & 0x1F);
- if (tmp >= 1 && tmp <= 12) {
- get_time(NVRAM, &tm);
- tm.tm_mon = tmp - 1;
- set_time(NVRAM, &tm);
- }
- break;
- case 0x1FFF:
- /* year */
- tmp = fromBCD(val);
- if (tmp >= 0 && tmp <= 99) {
- get_time(NVRAM, &tm);
- tm.tm_year = fromBCD(val);
- set_time(NVRAM, &tm);
- }
- break;
- default:
- /* Check lock registers state */
- if (NVRAM->addr >= 0x20 && NVRAM->addr <= 0x2F && (NVRAM->lock & 1))
- break;
- if (NVRAM->addr >= 0x30 && NVRAM->addr <= 0x3F && (NVRAM->lock & 2))
- break;
- if (NVRAM->addr < NVRAM_MAX_MEM ||
- (NVRAM->addr > 0x1FFF && NVRAM->addr < NVRAM->size)) {
- NVRAM->buffer[NVRAM->addr] = val & 0xFF;
- }
- break;
- }
-}
-
-uint32_t m48t08_read (m48t08_t *NVRAM)
-{
- struct tm tm;
- uint32_t retval = 0xFF;
-
- switch (NVRAM->addr) {
- case 0x1FF8:
- /* control */
- goto do_read;
- case 0x1FF9:
- /* seconds (BCD) */
- get_time(NVRAM, &tm);
- retval = (NVRAM->buffer[0x1FF9] & 0x80) | toBCD(tm.tm_sec);
- break;
- case 0x1FFA:
- /* minutes (BCD) */
- get_time(NVRAM, &tm);
- retval = toBCD(tm.tm_min);
- break;
- case 0x1FFB:
- /* hours (BCD) */
- get_time(NVRAM, &tm);
- retval = toBCD(tm.tm_hour);
- break;
- case 0x1FFC:
- /* day of the week / century */
- get_time(NVRAM, &tm);
- retval = NVRAM->buffer[0x1FFC] | tm.tm_wday;
- break;
- case 0x1FFD:
- /* date */
- get_time(NVRAM, &tm);
- retval = toBCD(tm.tm_mday);
- break;
- case 0x1FFE:
- /* month */
- get_time(NVRAM, &tm);
- retval = toBCD(tm.tm_mon + 1);
- break;
- case 0x1FFF:
- /* year */
- get_time(NVRAM, &tm);
- retval = toBCD(tm.tm_year);
- break;
- default:
- /* Check lock registers state */
- if (NVRAM->addr >= 0x20 && NVRAM->addr <= 0x2F && (NVRAM->lock & 1))
- break;
- if (NVRAM->addr >= 0x30 && NVRAM->addr <= 0x3F && (NVRAM->lock & 2))
- break;
- if (NVRAM->addr < NVRAM_MAX_MEM ||
- (NVRAM->addr > 0x1FFF && NVRAM->addr < NVRAM->size)) {
- do_read:
- retval = NVRAM->buffer[NVRAM->addr];
- }
- break;
- }
- if (NVRAM->addr > NVRAM_MAX_MEM + 1 && NVRAM->addr < 0x2000)
- NVRAM_PRINTF("0x%08x <= 0x%08x\n", NVRAM->addr, retval);
-
- return retval;
-}
-
-void m48t08_set_addr (m48t08_t *NVRAM, uint32_t addr)
-{
- NVRAM->addr = addr;
-}
-
-void m48t08_toggle_lock (m48t08_t *NVRAM, int lock)
-{
- NVRAM->lock ^= 1 << lock;
-}
-
-static void nvram_writeb (void *opaque, target_phys_addr_t addr, uint32_t value)
-{
- m48t08_t *NVRAM = opaque;
-
- addr -= NVRAM->mem_base;
- if (addr < NVRAM_MAX_MEM)
- NVRAM->buffer[addr] = value;
-}
-
-static void nvram_writew (void *opaque, target_phys_addr_t addr, uint32_t value)
-{
- m48t08_t *NVRAM = opaque;
-
- addr -= NVRAM->mem_base;
- if (addr < NVRAM_MAX_MEM) {
- NVRAM->buffer[addr] = value >> 8;
- NVRAM->buffer[addr + 1] = value;
- }
-}
-
-static void nvram_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
-{
- m48t08_t *NVRAM = opaque;
-
- addr -= NVRAM->mem_base;
- if (addr < NVRAM_MAX_MEM) {
- NVRAM->buffer[addr] = value >> 24;
- NVRAM->buffer[addr + 1] = value >> 16;
- NVRAM->buffer[addr + 2] = value >> 8;
- NVRAM->buffer[addr + 3] = value;
- }
-}
-
-static uint32_t nvram_readb (void *opaque, target_phys_addr_t addr)
-{
- m48t08_t *NVRAM = opaque;
- uint32_t retval = 0;
-
- addr -= NVRAM->mem_base;
- if (addr < NVRAM_MAX_MEM)
- retval = NVRAM->buffer[addr];
-
- return retval;
-}
-
-static uint32_t nvram_readw (void *opaque, target_phys_addr_t addr)
-{
- m48t08_t *NVRAM = opaque;
- uint32_t retval = 0;
-
- addr -= NVRAM->mem_base;
- if (addr < NVRAM_MAX_MEM) {
- retval = NVRAM->buffer[addr] << 8;
- retval |= NVRAM->buffer[addr + 1];
- }
-
- return retval;
-}
-
-static uint32_t nvram_readl (void *opaque, target_phys_addr_t addr)
-{
- m48t08_t *NVRAM = opaque;
- uint32_t retval = 0;
-
- addr -= NVRAM->mem_base;
- if (addr < NVRAM_MAX_MEM) {
- retval = NVRAM->buffer[addr] << 24;
- retval |= NVRAM->buffer[addr + 1] << 16;
- retval |= NVRAM->buffer[addr + 2] << 8;
- retval |= NVRAM->buffer[addr + 3];
- }
-
- return retval;
-}
-
-static CPUWriteMemoryFunc *nvram_write[] = {
- &nvram_writeb,
- &nvram_writew,
- &nvram_writel,
-};
-
-static CPUReadMemoryFunc *nvram_read[] = {
- &nvram_readb,
- &nvram_readw,
- &nvram_readl,
-};
-
-/* Initialisation routine */
-m48t08_t *m48t08_init(uint32_t mem_base, uint16_t size, uint8_t *macaddr)
-{
- m48t08_t *s;
- int i;
- unsigned char tmp = 0;
-
- s = qemu_mallocz(sizeof(m48t08_t));
- if (!s)
- return NULL;
- s->buffer = qemu_mallocz(size);
- if (!s->buffer) {
- qemu_free(s);
- return NULL;
- }
- s->size = size;
- s->mem_base = mem_base;
- s->addr = 0;
- if (mem_base != 0) {
- s->mem_index = cpu_register_io_memory(0, nvram_read, nvram_write, s);
- cpu_register_physical_memory(mem_base, 0x4000, s->mem_index);
- }
- s->lock = 0;
-
- i = 0x1fd8;
- s->buffer[i++] = 0x01;
- s->buffer[i++] = 0x80; /* Sun4m OBP */
- memcpy(&s->buffer[i], macaddr, 6);
-
- /* Calculate checksum */
- for (i = 0x1fd8; i < 0x1fe7; i++) {
- tmp ^= s->buffer[i];
- }
- s->buffer[0x1fe7] = tmp;
- return s;
-}
-
-#if 0
-struct idprom
-{
- unsigned char id_format; /* Format identifier (always 0x01) */
- unsigned char id_machtype; /* Machine type */
- unsigned char id_ethaddr[6]; /* Hardware ethernet address */
- long id_date; /* Date of manufacture */
- unsigned int id_sernum:24; /* Unique serial number */
- unsigned char id_cksum; /* Checksum - xor of the data bytes */
- unsigned char reserved[16];
-};
-#endif
+++ /dev/null
-#if !defined (__M48T08_H__)
-#define __M48T08_H__
-
-typedef struct m48t08_t m48t08_t;
-
-void m48t08_write (m48t08_t *NVRAM, uint32_t val);
-uint32_t m48t08_read (m48t08_t *NVRAM);
-void m48t08_set_addr (m48t08_t *NVRAM, uint32_t addr);
-void m48t08_toggle_lock (m48t08_t *NVRAM, int lock);
-m48t08_t *m48t08_init(uint32_t mem_base, uint16_t size, uint8_t *macaddr);
-
-#endif /* !defined (__M48T08_H__) */
+++ /dev/null
-/*
- * QEMU M48T59 NVRAM emulation for PPC PREP platform
- *
- * Copyright (c) 2003-2004 Jocelyn Mayer
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "vl.h"
-#include "m48t59.h"
-
-//#define DEBUG_NVRAM
-
-#if defined(DEBUG_NVRAM)
-#define NVRAM_PRINTF(fmt, args...) do { printf(fmt , ##args); } while (0)
-#else
-#define NVRAM_PRINTF(fmt, args...) do { } while (0)
-#endif
-
-struct m48t59_t {
- /* Hardware parameters */
- int IRQ;
- int mem_index;
- uint32_t mem_base;
- uint32_t io_base;
- uint16_t size;
- /* RTC management */
- time_t time_offset;
- time_t stop_time;
- /* Alarm & watchdog */
- time_t alarm;
- struct QEMUTimer *alrm_timer;
- struct QEMUTimer *wd_timer;
- /* NVRAM storage */
- uint8_t lock;
- uint16_t addr;
- uint8_t *buffer;
-};
-
-/* Fake timer functions */
-/* Generic helpers for BCD */
-static inline uint8_t toBCD (uint8_t value)
-{
- return (((value / 10) % 10) << 4) | (value % 10);
-}
-
-static inline uint8_t fromBCD (uint8_t BCD)
-{
- return ((BCD >> 4) * 10) + (BCD & 0x0F);
-}
-
-/* RTC management helpers */
-static void get_time (m48t59_t *NVRAM, struct tm *tm)
-{
- time_t t;
-
- t = time(NULL) + NVRAM->time_offset;
-#ifdef _WIN32
- memcpy(tm,localtime(&t),sizeof(*tm));
-#else
- localtime_r (&t, tm) ;
-#endif
-}
-
-static void set_time (m48t59_t *NVRAM, struct tm *tm)
-{
- time_t now, new_time;
-
- new_time = mktime(tm);
- now = time(NULL);
- NVRAM->time_offset = new_time - now;
-}
-
-/* Alarm management */
-static void alarm_cb (void *opaque)
-{
- struct tm tm, tm_now;
- uint64_t next_time;
- m48t59_t *NVRAM = opaque;
-
- pic_set_irq(NVRAM->IRQ, 1);
- if ((NVRAM->buffer[0x1FF5] & 0x80) == 0 &&
- (NVRAM->buffer[0x1FF4] & 0x80) == 0 &&
- (NVRAM->buffer[0x1FF3] & 0x80) == 0 &&
- (NVRAM->buffer[0x1FF2] & 0x80) == 0) {
- /* Repeat once a month */
- get_time(NVRAM, &tm_now);
- memcpy(&tm, &tm_now, sizeof(struct tm));
- tm.tm_mon++;
- if (tm.tm_mon == 13) {
- tm.tm_mon = 1;
- tm.tm_year++;
- }
- next_time = mktime(&tm);
- } else if ((NVRAM->buffer[0x1FF5] & 0x80) != 0 &&
- (NVRAM->buffer[0x1FF4] & 0x80) == 0 &&
- (NVRAM->buffer[0x1FF3] & 0x80) == 0 &&
- (NVRAM->buffer[0x1FF2] & 0x80) == 0) {
- /* Repeat once a day */
- next_time = 24 * 60 * 60 + mktime(&tm_now);
- } else if ((NVRAM->buffer[0x1FF5] & 0x80) != 0 &&
- (NVRAM->buffer[0x1FF4] & 0x80) != 0 &&
- (NVRAM->buffer[0x1FF3] & 0x80) == 0 &&
- (NVRAM->buffer[0x1FF2] & 0x80) == 0) {
- /* Repeat once an hour */
- next_time = 60 * 60 + mktime(&tm_now);
- } else if ((NVRAM->buffer[0x1FF5] & 0x80) != 0 &&
- (NVRAM->buffer[0x1FF4] & 0x80) != 0 &&
- (NVRAM->buffer[0x1FF3] & 0x80) != 0 &&
- (NVRAM->buffer[0x1FF2] & 0x80) == 0) {
- /* Repeat once a minute */
- next_time = 60 + mktime(&tm_now);
- } else {
- /* Repeat once a second */
- next_time = 1 + mktime(&tm_now);
- }
- qemu_mod_timer(NVRAM->alrm_timer, next_time * 1000);
- pic_set_irq(NVRAM->IRQ, 0);
-}
-
-
-static void get_alarm (m48t59_t *NVRAM, struct tm *tm)
-{
-#ifdef _WIN32
- memcpy(tm,localtime(&NVRAM->alarm),sizeof(*tm));
-#else
- localtime_r (&NVRAM->alarm, tm);
-#endif
-}
-
-static void set_alarm (m48t59_t *NVRAM, struct tm *tm)
-{
- NVRAM->alarm = mktime(tm);
- if (NVRAM->alrm_timer != NULL) {
- qemu_del_timer(NVRAM->alrm_timer);
- NVRAM->alrm_timer = NULL;
- }
- if (NVRAM->alarm - time(NULL) > 0)
- qemu_mod_timer(NVRAM->alrm_timer, NVRAM->alarm * 1000);
-}
-
-/* Watchdog management */
-static void watchdog_cb (void *opaque)
-{
- m48t59_t *NVRAM = opaque;
-
- NVRAM->buffer[0x1FF0] |= 0x80;
- if (NVRAM->buffer[0x1FF7] & 0x80) {
- NVRAM->buffer[0x1FF7] = 0x00;
- NVRAM->buffer[0x1FFC] &= ~0x40;
- /* May it be a hw CPU Reset instead ? */
- qemu_system_reset_request();
- } else {
- pic_set_irq(NVRAM->IRQ, 1);
- pic_set_irq(NVRAM->IRQ, 0);
- }
-}
-
-static void set_up_watchdog (m48t59_t *NVRAM, uint8_t value)
-{
- uint64_t interval; /* in 1/16 seconds */
-
- if (NVRAM->wd_timer != NULL) {
- qemu_del_timer(NVRAM->wd_timer);
- NVRAM->wd_timer = NULL;
- }
- NVRAM->buffer[0x1FF0] &= ~0x80;
- if (value != 0) {
- interval = (1 << (2 * (value & 0x03))) * ((value >> 2) & 0x1F);
- qemu_mod_timer(NVRAM->wd_timer, ((uint64_t)time(NULL) * 1000) +
- ((interval * 1000) >> 4));
- }
-}
-
-/* Direct access to NVRAM */
-void m48t59_write (m48t59_t *NVRAM, uint32_t val)
-{
- struct tm tm;
- int tmp;
-
- if (NVRAM->addr > 0x1FF8 && NVRAM->addr < 0x2000)
- NVRAM_PRINTF("%s: 0x%08x => 0x%08x\n", __func__, NVRAM->addr, val);
- switch (NVRAM->addr) {
- case 0x1FF0:
- /* flags register : read-only */
- break;
- case 0x1FF1:
- /* unused */
- break;
- case 0x1FF2:
- /* alarm seconds */
- tmp = fromBCD(val & 0x7F);
- if (tmp >= 0 && tmp <= 59) {
- get_alarm(NVRAM, &tm);
- tm.tm_sec = tmp;
- NVRAM->buffer[0x1FF2] = val;
- set_alarm(NVRAM, &tm);
- }
- break;
- case 0x1FF3:
- /* alarm minutes */
- tmp = fromBCD(val & 0x7F);
- if (tmp >= 0 && tmp <= 59) {
- get_alarm(NVRAM, &tm);
- tm.tm_min = tmp;
- NVRAM->buffer[0x1FF3] = val;
- set_alarm(NVRAM, &tm);
- }
- break;
- case 0x1FF4:
- /* alarm hours */
- tmp = fromBCD(val & 0x3F);
- if (tmp >= 0 && tmp <= 23) {
- get_alarm(NVRAM, &tm);
- tm.tm_hour = tmp;
- NVRAM->buffer[0x1FF4] = val;
- set_alarm(NVRAM, &tm);
- }
- break;
- case 0x1FF5:
- /* alarm date */
- tmp = fromBCD(val & 0x1F);
- if (tmp != 0) {
- get_alarm(NVRAM, &tm);
- tm.tm_mday = tmp;
- NVRAM->buffer[0x1FF5] = val;
- set_alarm(NVRAM, &tm);
- }
- break;
- case 0x1FF6:
- /* interrupts */
- NVRAM->buffer[0x1FF6] = val;
- break;
- case 0x1FF7:
- /* watchdog */
- NVRAM->buffer[0x1FF7] = val;
- set_up_watchdog(NVRAM, val);
- break;
- case 0x1FF8:
- /* control */
- NVRAM->buffer[0x1FF8] = (val & ~0xA0) | 0x90;
- break;
- case 0x1FF9:
- /* seconds (BCD) */
- tmp = fromBCD(val & 0x7F);
- if (tmp >= 0 && tmp <= 59) {
- get_time(NVRAM, &tm);
- tm.tm_sec = tmp;
- set_time(NVRAM, &tm);
- }
- if ((val & 0x80) ^ (NVRAM->buffer[0x1FF9] & 0x80)) {
- if (val & 0x80) {
- NVRAM->stop_time = time(NULL);
- } else {
- NVRAM->time_offset += NVRAM->stop_time - time(NULL);
- NVRAM->stop_time = 0;
- }
- }
- NVRAM->buffer[0x1FF9] = val & 0x80;
- break;
- case 0x1FFA:
- /* minutes (BCD) */
- tmp = fromBCD(val & 0x7F);
- if (tmp >= 0 && tmp <= 59) {
- get_time(NVRAM, &tm);
- tm.tm_min = tmp;
- set_time(NVRAM, &tm);
- }
- break;
- case 0x1FFB:
- /* hours (BCD) */
- tmp = fromBCD(val & 0x3F);
- if (tmp >= 0 && tmp <= 23) {
- get_time(NVRAM, &tm);
- tm.tm_hour = tmp;
- set_time(NVRAM, &tm);
- }
- break;
- case 0x1FFC:
- /* day of the week / century */
- tmp = fromBCD(val & 0x07);
- get_time(NVRAM, &tm);
- tm.tm_wday = tmp;
- set_time(NVRAM, &tm);
- NVRAM->buffer[0x1FFC] = val & 0x40;
- break;
- case 0x1FFD:
- /* date */
- tmp = fromBCD(val & 0x1F);
- if (tmp != 0) {
- get_time(NVRAM, &tm);
- tm.tm_mday = tmp;
- set_time(NVRAM, &tm);
- }
- break;
- case 0x1FFE:
- /* month */
- tmp = fromBCD(val & 0x1F);
- if (tmp >= 1 && tmp <= 12) {
- get_time(NVRAM, &tm);
- tm.tm_mon = tmp - 1;
- set_time(NVRAM, &tm);
- }
- break;
- case 0x1FFF:
- /* year */
- tmp = fromBCD(val);
- if (tmp >= 0 && tmp <= 99) {
- get_time(NVRAM, &tm);
- tm.tm_year = fromBCD(val);
- set_time(NVRAM, &tm);
- }
- break;
- default:
- /* Check lock registers state */
- if (NVRAM->addr >= 0x20 && NVRAM->addr <= 0x2F && (NVRAM->lock & 1))
- break;
- if (NVRAM->addr >= 0x30 && NVRAM->addr <= 0x3F && (NVRAM->lock & 2))
- break;
- if (NVRAM->addr < 0x1FF0 ||
- (NVRAM->addr > 0x1FFF && NVRAM->addr < NVRAM->size)) {
- NVRAM->buffer[NVRAM->addr] = val & 0xFF;
- }
- break;
- }
-}
-
-uint32_t m48t59_read (m48t59_t *NVRAM)
-{
- struct tm tm;
- uint32_t retval = 0xFF;
-
- switch (NVRAM->addr) {
- case 0x1FF0:
- /* flags register */
- goto do_read;
- case 0x1FF1:
- /* unused */
- retval = 0;
- break;
- case 0x1FF2:
- /* alarm seconds */
- goto do_read;
- case 0x1FF3:
- /* alarm minutes */
- goto do_read;
- case 0x1FF4:
- /* alarm hours */
- goto do_read;
- case 0x1FF5:
- /* alarm date */
- goto do_read;
- case 0x1FF6:
- /* interrupts */
- goto do_read;
- case 0x1FF7:
- /* A read resets the watchdog */
- set_up_watchdog(NVRAM, NVRAM->buffer[0x1FF7]);
- goto do_read;
- case 0x1FF8:
- /* control */
- goto do_read;
- case 0x1FF9:
- /* seconds (BCD) */
- get_time(NVRAM, &tm);
- retval = (NVRAM->buffer[0x1FF9] & 0x80) | toBCD(tm.tm_sec);
- break;
- case 0x1FFA:
- /* minutes (BCD) */
- get_time(NVRAM, &tm);
- retval = toBCD(tm.tm_min);
- break;
- case 0x1FFB:
- /* hours (BCD) */
- get_time(NVRAM, &tm);
- retval = toBCD(tm.tm_hour);
- break;
- case 0x1FFC:
- /* day of the week / century */
- get_time(NVRAM, &tm);
- retval = NVRAM->buffer[0x1FFC] | tm.tm_wday;
- break;
- case 0x1FFD:
- /* date */
- get_time(NVRAM, &tm);
- retval = toBCD(tm.tm_mday);
- break;
- case 0x1FFE:
- /* month */
- get_time(NVRAM, &tm);
- retval = toBCD(tm.tm_mon + 1);
- break;
- case 0x1FFF:
- /* year */
- get_time(NVRAM, &tm);
- retval = toBCD(tm.tm_year);
- break;
- default:
- /* Check lock registers state */
- if (NVRAM->addr >= 0x20 && NVRAM->addr <= 0x2F && (NVRAM->lock & 1))
- break;
- if (NVRAM->addr >= 0x30 && NVRAM->addr <= 0x3F && (NVRAM->lock & 2))
- break;
- if (NVRAM->addr < 0x1FF0 ||
- (NVRAM->addr > 0x1FFF && NVRAM->addr < NVRAM->size)) {
- do_read:
- retval = NVRAM->buffer[NVRAM->addr];
- }
- break;
- }
- if (NVRAM->addr > 0x1FF9 && NVRAM->addr < 0x2000)
- NVRAM_PRINTF("0x%08x <= 0x%08x\n", NVRAM->addr, retval);
-
- return retval;
-}
-
-void m48t59_set_addr (m48t59_t *NVRAM, uint32_t addr)
-{
- NVRAM->addr = addr;
-}
-
-void m48t59_toggle_lock (m48t59_t *NVRAM, int lock)
-{
- NVRAM->lock ^= 1 << lock;
-}
-
-/* IO access to NVRAM */
-static void NVRAM_writeb (void *opaque, uint32_t addr, uint32_t val)
-{
- m48t59_t *NVRAM = opaque;
-
- addr -= NVRAM->io_base;
- NVRAM_PRINTF("0x%08x => 0x%08x\n", addr, val);
- switch (addr) {
- case 0:
- NVRAM->addr &= ~0x00FF;
- NVRAM->addr |= val;
- break;
- case 1:
- NVRAM->addr &= ~0xFF00;
- NVRAM->addr |= val << 8;
- break;
- case 3:
- m48t59_write(NVRAM, val);
- NVRAM->addr = 0x0000;
- break;
- default:
- break;
- }
-}
-
-static uint32_t NVRAM_readb (void *opaque, uint32_t addr)
-{
- m48t59_t *NVRAM = opaque;
- uint32_t retval;
-
- addr -= NVRAM->io_base;
- switch (addr) {
- case 3:
- retval = m48t59_read(NVRAM);
- break;
- default:
- retval = -1;
- break;
- }
- NVRAM_PRINTF("0x%08x <= 0x%08x\n", addr, retval);
-
- return retval;
-}
-
-static void nvram_writeb (void *opaque, target_phys_addr_t addr, uint32_t value)
-{
- m48t59_t *NVRAM = opaque;
-
- addr -= NVRAM->mem_base;
- if (addr < 0x1FF0)
- NVRAM->buffer[addr] = value;
-}
-
-static void nvram_writew (void *opaque, target_phys_addr_t addr, uint32_t value)
-{
- m48t59_t *NVRAM = opaque;
-
- addr -= NVRAM->mem_base;
- if (addr < 0x1FF0) {
- NVRAM->buffer[addr] = value >> 8;
- NVRAM->buffer[addr + 1] = value;
- }
-}
-
-static void nvram_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
-{
- m48t59_t *NVRAM = opaque;
-
- addr -= NVRAM->mem_base;
- if (addr < 0x1FF0) {
- NVRAM->buffer[addr] = value >> 24;
- NVRAM->buffer[addr + 1] = value >> 16;
- NVRAM->buffer[addr + 2] = value >> 8;
- NVRAM->buffer[addr + 3] = value;
- }
-}
-
-static uint32_t nvram_readb (void *opaque, target_phys_addr_t addr)
-{
- m48t59_t *NVRAM = opaque;
- uint32_t retval = 0;
-
- addr -= NVRAM->mem_base;
- if (addr < 0x1FF0)
- retval = NVRAM->buffer[addr];
-
- return retval;
-}
-
-static uint32_t nvram_readw (void *opaque, target_phys_addr_t addr)
-{
- m48t59_t *NVRAM = opaque;
- uint32_t retval = 0;
-
- addr -= NVRAM->mem_base;
- if (addr < 0x1FF0) {
- retval = NVRAM->buffer[addr] << 8;
- retval |= NVRAM->buffer[addr + 1];
- }
-
- return retval;
-}
-
-static uint32_t nvram_readl (void *opaque, target_phys_addr_t addr)
-{
- m48t59_t *NVRAM = opaque;
- uint32_t retval = 0;
-
- addr -= NVRAM->mem_base;
- if (addr < 0x1FF0) {
- retval = NVRAM->buffer[addr] << 24;
- retval |= NVRAM->buffer[addr + 1] << 16;
- retval |= NVRAM->buffer[addr + 2] << 8;
- retval |= NVRAM->buffer[addr + 3];
- }
-
- return retval;
-}
-
-static CPUWriteMemoryFunc *nvram_write[] = {
- &nvram_writeb,
- &nvram_writew,
- &nvram_writel,
-};
-
-static CPUReadMemoryFunc *nvram_read[] = {
- &nvram_readb,
- &nvram_readw,
- &nvram_readl,
-};
-/* Initialisation routine */
-m48t59_t *m48t59_init (int IRQ, uint32_t mem_base,
- uint32_t io_base, uint16_t size)
-{
- m48t59_t *s;
-
- s = qemu_mallocz(sizeof(m48t59_t));
- if (!s)
- return NULL;
- s->buffer = qemu_mallocz(size);
- if (!s->buffer) {
- qemu_free(s);
- return NULL;
- }
- s->IRQ = IRQ;
- s->size = size;
- s->mem_base = mem_base;
- s->io_base = io_base;
- s->addr = 0;
- register_ioport_read(io_base, 0x04, 1, NVRAM_readb, s);
- register_ioport_write(io_base, 0x04, 1, NVRAM_writeb, s);
- if (mem_base != 0) {
- s->mem_index = cpu_register_io_memory(0, nvram_read, nvram_write, s);
- cpu_register_physical_memory(mem_base, 0x4000, s->mem_index);
- }
- s->alrm_timer = qemu_new_timer(vm_clock, &alarm_cb, s);
- s->wd_timer = qemu_new_timer(vm_clock, &watchdog_cb, s);
- s->lock = 0;
-
- return s;
-}
+++ /dev/null
-#if !defined (__M48T59_H__)
-#define __M48T59_H__
-
-typedef struct m48t59_t m48t59_t;
-
-void m48t59_write (m48t59_t *NVRAM, uint32_t val);
-uint32_t m48t59_read (m48t59_t *NVRAM);
-void m48t59_set_addr (m48t59_t *NVRAM, uint32_t addr);
-void m48t59_toggle_lock (m48t59_t *NVRAM, int lock);
-m48t59_t *m48t59_init (int IRQ, uint32_t io_base,
- uint32_t mem_base, uint16_t size);
-
-#endif /* !defined (__M48T59_H__) */
+++ /dev/null
-#include "vl.h"
-#include "disas.h"
-
-#define ELF_CLASS ELFCLASS32
-#define ELF_DATA ELFDATA2MSB
-#define ELF_ARCH EM_SPARC
-
-#include "elf.h"
-
-#ifdef BSWAP_NEEDED
-static void bswap_ehdr(Elf32_Ehdr *ehdr)
-{
- bswap16s(&ehdr->e_type); /* Object file type */
- bswap16s(&ehdr->e_machine); /* Architecture */
- bswap32s(&ehdr->e_version); /* Object file version */
- bswap32s(&ehdr->e_entry); /* Entry point virtual address */
- bswap32s(&ehdr->e_phoff); /* Program header table file offset */
- bswap32s(&ehdr->e_shoff); /* Section header table file offset */
- bswap32s(&ehdr->e_flags); /* Processor-specific flags */
- bswap16s(&ehdr->e_ehsize); /* ELF header size in bytes */
- bswap16s(&ehdr->e_phentsize); /* Program header table entry size */
- bswap16s(&ehdr->e_phnum); /* Program header table entry count */
- bswap16s(&ehdr->e_shentsize); /* Section header table entry size */
- bswap16s(&ehdr->e_shnum); /* Section header table entry count */
- bswap16s(&ehdr->e_shstrndx); /* Section header string table index */
-}
-
-static void bswap_phdr(Elf32_Phdr *phdr)
-{
- bswap32s(&phdr->p_type); /* Segment type */
- bswap32s(&phdr->p_offset); /* Segment file offset */
- bswap32s(&phdr->p_vaddr); /* Segment virtual address */
- bswap32s(&phdr->p_paddr); /* Segment physical address */
- bswap32s(&phdr->p_filesz); /* Segment size in file */
- bswap32s(&phdr->p_memsz); /* Segment size in memory */
- bswap32s(&phdr->p_flags); /* Segment flags */
- bswap32s(&phdr->p_align); /* Segment alignment */
-}
-
-static void bswap_shdr(Elf32_Shdr *shdr)
-{
- bswap32s(&shdr->sh_name);
- bswap32s(&shdr->sh_type);
- bswap32s(&shdr->sh_flags);
- bswap32s(&shdr->sh_addr);
- bswap32s(&shdr->sh_offset);
- bswap32s(&shdr->sh_size);
- bswap32s(&shdr->sh_link);
- bswap32s(&shdr->sh_info);
- bswap32s(&shdr->sh_addralign);
- bswap32s(&shdr->sh_entsize);
-}
-
-static void bswap_sym(Elf32_Sym *sym)
-{
- bswap32s(&sym->st_name);
- bswap32s(&sym->st_value);
- bswap32s(&sym->st_size);
- bswap16s(&sym->st_shndx);
-}
-#else
-#define bswap_ehdr(e) do { } while (0)
-#define bswap_phdr(e) do { } while (0)
-#define bswap_shdr(e) do { } while (0)
-#define bswap_sym(e) do { } while (0)
-#endif
-
-static int find_phdr(struct elfhdr *ehdr, int fd, struct elf_phdr *phdr, uint32_t type)
-{
- int i, retval;
-
- retval = lseek(fd, ehdr->e_phoff, SEEK_SET);
- if (retval < 0)
- return -1;
-
- for (i = 0; i < ehdr->e_phnum; i++) {
- retval = read(fd, phdr, sizeof(*phdr));
- if (retval < 0)
- return -1;
- bswap_phdr(phdr);
- if (phdr->p_type == type)
- return 0;
- }
- return -1;
-}
-
-static void *find_shdr(struct elfhdr *ehdr, int fd, struct elf_shdr *shdr, uint32_t type)
-{
- int i, retval;
-
- retval = lseek(fd, ehdr->e_shoff, SEEK_SET);
- if (retval < 0)
- return NULL;
-
- for (i = 0; i < ehdr->e_shnum; i++) {
- retval = read(fd, shdr, sizeof(*shdr));
- if (retval < 0)
- return NULL;
- bswap_shdr(shdr);
- if (shdr->sh_type == type)
- return qemu_malloc(shdr->sh_size);
- }
- return NULL;
-}
-
-static int find_strtab(struct elfhdr *ehdr, int fd, struct elf_shdr *shdr, struct elf_shdr *symtab)
-{
- int retval;
-
- retval = lseek(fd, ehdr->e_shoff + sizeof(struct elf_shdr) * symtab->sh_link, SEEK_SET);
- if (retval < 0)
- return -1;
-
- retval = read(fd, shdr, sizeof(*shdr));
- if (retval < 0)
- return -1;
- bswap_shdr(shdr);
- if (shdr->sh_type == SHT_STRTAB)
- return qemu_malloc(shdr->sh_size);;
- return 0;
-}
-
-static int read_program(int fd, struct elf_phdr *phdr, void *dst)
-{
- int retval;
- retval = lseek(fd, 0x4000, SEEK_SET);
- if (retval < 0)
- return -1;
- return read(fd, dst, phdr->p_filesz);
-}
-
-static int read_section(int fd, struct elf_shdr *s, void *dst)
-{
- int retval;
-
- retval = lseek(fd, s->sh_offset, SEEK_SET);
- if (retval < 0)
- return -1;
- retval = read(fd, dst, s->sh_size);
- if (retval < 0)
- return -1;
- return 0;
-}
-
-static void *process_section(struct elfhdr *ehdr, int fd, struct elf_shdr *shdr, uint32_t type)
-{
- void *dst;
-
- dst = find_shdr(ehdr, fd, shdr, type);
- if (!dst)
- goto error;
-
- if (read_section(fd, shdr, dst))
- goto error;
- return dst;
- error:
- qemu_free(dst);
- return NULL;
-}
-
-static void *process_strtab(struct elfhdr *ehdr, int fd, struct elf_shdr *shdr, struct elf_shdr *symtab)
-{
- void *dst;
-
- dst = find_strtab(ehdr, fd, shdr, symtab);
- if (!dst)
- goto error;
-
- if (read_section(fd, shdr, dst))
- goto error;
- return dst;
- error:
- qemu_free(dst);
- return NULL;
-}
-
-static void load_symbols(struct elfhdr *ehdr, int fd)
-{
- struct elf_shdr symtab, strtab;
- struct elf_sym *syms;
- int nsyms, i;
- char *str;
-
- /* Symbol table */
- syms = process_section(ehdr, fd, &symtab, SHT_SYMTAB);
- if (!syms)
- return;
-
- nsyms = symtab.sh_size / sizeof(struct elf_sym);
- for (i = 0; i < nsyms; i++)
- bswap_sym(&syms[i]);
-
- /* String table */
- str = process_strtab(ehdr, fd, &strtab, &symtab);
- if (!str)
- goto error_freesyms;
-
- /* Commit */
- qemu_free(disas_symtab); /* XXX Merge with old symbols? */
- qemu_free(disas_strtab);
- disas_symtab = syms;
- disas_num_syms = nsyms;
- disas_strtab = str;
- return;
- error_freesyms:
- qemu_free(syms);
- return;
-}
-
-int load_elf(const char * filename, uint8_t *addr)
-{
- struct elfhdr ehdr;
- struct elf_phdr phdr;
- int retval, fd;
-
- fd = open(filename, O_RDONLY | O_BINARY);
- if (fd < 0)
- goto error;
-
- retval = read(fd, &ehdr, sizeof(ehdr));
- if (retval < 0)
- goto error;
-
- bswap_ehdr(&ehdr);
-
- if (ehdr.e_ident[0] != 0x7f || ehdr.e_ident[1] != 'E'
- || ehdr.e_ident[2] != 'L' || ehdr.e_ident[3] != 'F'
- || ehdr.e_machine != EM_SPARC)
- goto error;
-
- if (find_phdr(&ehdr, fd, &phdr, PT_LOAD))
- goto error;
- retval = read_program(fd, &phdr, addr);
- if (retval < 0)
- goto error;
-
- load_symbols(&ehdr, fd);
-
- close(fd);
- return retval;
- error:
- close(fd);
- return -1;
-}
-
-int load_kernel(const char *filename, uint8_t *addr)
-{
- int fd, size;
-
- fd = open(filename, O_RDONLY | O_BINARY);
- if (fd < 0)
- return -1;
- /* load 32 bit code */
- size = read(fd, addr, 16 * 1024 * 1024);
- if (size < 0)
- goto fail;
- close(fd);
- return size;
- fail:
- close(fd);
- return -1;
-}
-
-typedef struct MAGICState {
- uint32_t addr;
- uint32_t saved_addr;
- int magic_state;
- char saved_kfn[1024];
-} MAGICState;
-
-static uint32_t magic_mem_readl(void *opaque, target_phys_addr_t addr)
-{
- int ret;
- MAGICState *s = opaque;
-
- if (s->magic_state == 0) {
- ret = load_elf(s->saved_kfn, (uint8_t *)s->saved_addr);
- if (ret < 0)
- ret = load_kernel(s->saved_kfn, (uint8_t *)s->saved_addr);
- if (ret < 0) {
- fprintf(stderr, "qemu: could not load kernel '%s'\n",
- s->saved_kfn);
- }
- s->magic_state = 1; /* No more magic */
- tb_flush();
- return bswap32(ret);
- }
- return 0;
-}
-
-static void magic_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
-}
-
-
-static CPUReadMemoryFunc *magic_mem_read[3] = {
- magic_mem_readl,
- magic_mem_readl,
- magic_mem_readl,
-};
-
-static CPUWriteMemoryFunc *magic_mem_write[3] = {
- magic_mem_writel,
- magic_mem_writel,
- magic_mem_writel,
-};
-
-void magic_init(const char *kfn, int kloadaddr, uint32_t addr)
-{
- int magic_io_memory;
- MAGICState *s;
-
- s = qemu_mallocz(sizeof(MAGICState));
- if (!s)
- return;
-
- strcpy(s->saved_kfn, kfn);
- s->saved_addr = kloadaddr;
- s->magic_state = 0;
- s->addr = addr;
- magic_io_memory = cpu_register_io_memory(0, magic_mem_read, magic_mem_write, s);
- cpu_register_physical_memory(addr, 4, magic_io_memory);
-}
-
+++ /dev/null
-/*
- * QEMU MC146818 RTC emulation
- *
- * Copyright (c) 2003-2004 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "vl.h"
-
-//#define DEBUG_CMOS
-
-#define RTC_SECONDS 0
-#define RTC_SECONDS_ALARM 1
-#define RTC_MINUTES 2
-#define RTC_MINUTES_ALARM 3
-#define RTC_HOURS 4
-#define RTC_HOURS_ALARM 5
-#define RTC_ALARM_DONT_CARE 0xC0
-
-#define RTC_DAY_OF_WEEK 6
-#define RTC_DAY_OF_MONTH 7
-#define RTC_MONTH 8
-#define RTC_YEAR 9
-
-#define RTC_REG_A 10
-#define RTC_REG_B 11
-#define RTC_REG_C 12
-#define RTC_REG_D 13
-
-#define REG_A_UIP 0x80
-
-#define REG_B_SET 0x80
-#define REG_B_PIE 0x40
-#define REG_B_AIE 0x20
-#define REG_B_UIE 0x10
-
-struct RTCState {
- uint8_t cmos_data[128];
- uint8_t cmos_index;
- struct tm current_tm;
- int irq;
- /* periodic timer */
- QEMUTimer *periodic_timer;
- int64_t next_periodic_time;
- /* second update */
- int64_t next_second_time;
- QEMUTimer *second_timer;
- QEMUTimer *second_timer2;
-};
-
-static void rtc_set_time(RTCState *s);
-static void rtc_copy_date(RTCState *s);
-
-static void rtc_timer_update(RTCState *s, int64_t current_time)
-{
- int period_code, period;
- int64_t cur_clock, next_irq_clock;
-
- period_code = s->cmos_data[RTC_REG_A] & 0x0f;
- if (period_code != 0 &&
- (s->cmos_data[RTC_REG_B] & REG_B_PIE)) {
- if (period_code <= 2)
- period_code += 7;
- /* period in 32 Khz cycles */
- period = 1 << (period_code - 1);
- /* compute 32 khz clock */
- cur_clock = muldiv64(current_time, 32768, ticks_per_sec);
- next_irq_clock = (cur_clock & ~(period - 1)) + period;
- s->next_periodic_time = muldiv64(next_irq_clock, ticks_per_sec, 32768) + 1;
- qemu_mod_timer(s->periodic_timer, s->next_periodic_time);
- } else {
- qemu_del_timer(s->periodic_timer);
- }
-}
-
-static void rtc_periodic_timer(void *opaque)
-{
- RTCState *s = opaque;
-
- rtc_timer_update(s, s->next_periodic_time);
- s->cmos_data[RTC_REG_C] |= 0xc0;
- pic_set_irq(s->irq, 1);
-}
-
-static void cmos_ioport_write(void *opaque, uint32_t addr, uint32_t data)
-{
- RTCState *s = opaque;
-
- if ((addr & 1) == 0) {
- s->cmos_index = data & 0x7f;
- } else {
-#ifdef DEBUG_CMOS
- printf("cmos: write index=0x%02x val=0x%02x\n",
- s->cmos_index, data);
-#endif
- switch(s->cmos_index) {
- case RTC_SECONDS_ALARM:
- case RTC_MINUTES_ALARM:
- case RTC_HOURS_ALARM:
- /* XXX: not supported */
- s->cmos_data[s->cmos_index] = data;
- break;
- case RTC_SECONDS:
- case RTC_MINUTES:
- case RTC_HOURS:
- case RTC_DAY_OF_WEEK:
- case RTC_DAY_OF_MONTH:
- case RTC_MONTH:
- case RTC_YEAR:
- s->cmos_data[s->cmos_index] = data;
- /* if in set mode, do not update the time */
- if (!(s->cmos_data[RTC_REG_B] & REG_B_SET)) {
- rtc_set_time(s);
- }
- break;
- case RTC_REG_A:
- /* UIP bit is read only */
- s->cmos_data[RTC_REG_A] = (data & ~REG_A_UIP) |
- (s->cmos_data[RTC_REG_A] & REG_A_UIP);
- rtc_timer_update(s, qemu_get_clock(vm_clock));
- break;
- case RTC_REG_B:
- if (data & REG_B_SET) {
- /* set mode: reset UIP mode */
- s->cmos_data[RTC_REG_A] &= ~REG_A_UIP;
- data &= ~REG_B_UIE;
- } else {
- /* if disabling set mode, update the time */
- if (s->cmos_data[RTC_REG_B] & REG_B_SET) {
- rtc_set_time(s);
- }
- }
- s->cmos_data[RTC_REG_B] = data;
- rtc_timer_update(s, qemu_get_clock(vm_clock));
- break;
- case RTC_REG_C:
- case RTC_REG_D:
- /* cannot write to them */
- break;
- default:
- s->cmos_data[s->cmos_index] = data;
- break;
- }
- }
-}
-
-static inline int to_bcd(RTCState *s, int a)
-{
- if (s->cmos_data[RTC_REG_B] & 0x04) {
- return a;
- } else {
- return ((a / 10) << 4) | (a % 10);
- }
-}
-
-static inline int from_bcd(RTCState *s, int a)
-{
- if (s->cmos_data[RTC_REG_B] & 0x04) {
- return a;
- } else {
- return ((a >> 4) * 10) + (a & 0x0f);
- }
-}
-
-static void send_timeoffset_msg(time_t delta)
-{
-
-/* This routine is used to inform another entity that the
- base time offset has changed. For instance, if you
- were using xenstore, you might want to write to the store
- at this point. Or, you might use some other method.
- Whatever you might choose, here's a hook point to implement it.
-
- One item of note is that this delta is in addition to
- any existing offset you might be already using. */
-
- return;
-}
-
-static void rtc_set_time(RTCState *s)
-{
- struct tm *tm = &s->current_tm;
- time_t before, after;
-
- before = mktime(tm);
- tm->tm_sec = from_bcd(s, s->cmos_data[RTC_SECONDS]);
- tm->tm_min = from_bcd(s, s->cmos_data[RTC_MINUTES]);
- tm->tm_hour = from_bcd(s, s->cmos_data[RTC_HOURS] & 0x7f);
- if (!(s->cmos_data[RTC_REG_B] & 0x02) &&
- (s->cmos_data[RTC_HOURS] & 0x80)) {
- tm->tm_hour += 12;
- }
- tm->tm_wday = from_bcd(s, s->cmos_data[RTC_DAY_OF_WEEK]);
- tm->tm_mday = from_bcd(s, s->cmos_data[RTC_DAY_OF_MONTH]);
- tm->tm_mon = from_bcd(s, s->cmos_data[RTC_MONTH]) - 1;
- tm->tm_year = from_bcd(s, s->cmos_data[RTC_YEAR]) + 100;
-
- /* Compute, and send, the additional time delta
- We could compute the total time delta, but this is
- sufficient, and simple. */
- after = mktime(tm);
- send_timeoffset_msg(after-before);
-}
-
-static void rtc_copy_date(RTCState *s)
-{
- const struct tm *tm = &s->current_tm;
-
- s->cmos_data[RTC_SECONDS] = to_bcd(s, tm->tm_sec);
- s->cmos_data[RTC_MINUTES] = to_bcd(s, tm->tm_min);
- if (s->cmos_data[RTC_REG_B] & 0x02) {
- /* 24 hour format */
- s->cmos_data[RTC_HOURS] = to_bcd(s, tm->tm_hour);
- } else {
- /* 12 hour format */
- s->cmos_data[RTC_HOURS] = to_bcd(s, tm->tm_hour % 12);
- if (tm->tm_hour >= 12)
- s->cmos_data[RTC_HOURS] |= 0x80;
- }
- s->cmos_data[RTC_DAY_OF_WEEK] = to_bcd(s, tm->tm_wday);
- s->cmos_data[RTC_DAY_OF_MONTH] = to_bcd(s, tm->tm_mday);
- s->cmos_data[RTC_MONTH] = to_bcd(s, tm->tm_mon + 1);
- s->cmos_data[RTC_YEAR] = to_bcd(s, tm->tm_year % 100);
-}
-
-/* month is between 0 and 11. */
-static int get_days_in_month(int month, int year)
-{
- static const int days_tab[12] = {
- 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
- };
- int d;
- if ((unsigned )month >= 12)
- return 31;
- d = days_tab[month];
- if (month == 1) {
- if ((year % 4) == 0 && ((year % 100) != 0 || (year % 400) == 0))
- d++;
- }
- return d;
-}
-
-/* update 'tm' to the next second */
-static void rtc_next_second(struct tm *tm)
-{
- int days_in_month;
-
- tm->tm_sec++;
- if ((unsigned)tm->tm_sec >= 60) {
- tm->tm_sec = 0;
- tm->tm_min++;
- if ((unsigned)tm->tm_min >= 60) {
- tm->tm_min = 0;
- tm->tm_hour++;
- if ((unsigned)tm->tm_hour >= 24) {
- tm->tm_hour = 0;
- /* next day */
- tm->tm_wday++;
- if ((unsigned)tm->tm_wday >= 7)
- tm->tm_wday = 0;
- days_in_month = get_days_in_month(tm->tm_mon,
- tm->tm_year + 1900);
- tm->tm_mday++;
- if (tm->tm_mday < 1) {
- tm->tm_mday = 1;
- } else if (tm->tm_mday > days_in_month) {
- tm->tm_mday = 1;
- tm->tm_mon++;
- if (tm->tm_mon >= 12) {
- tm->tm_mon = 0;
- tm->tm_year++;
- }
- }
- }
- }
- }
-}
-
-
-static void rtc_update_second(void *opaque)
-{
- RTCState *s = opaque;
- int64_t delay;
-
- /* if the oscillator is not in normal operation, we do not update */
- if ((s->cmos_data[RTC_REG_A] & 0x70) != 0x20) {
- s->next_second_time += ticks_per_sec;
- qemu_mod_timer(s->second_timer, s->next_second_time);
- } else {
- rtc_next_second(&s->current_tm);
-
- if (!(s->cmos_data[RTC_REG_B] & REG_B_SET)) {
- /* update in progress bit */
- s->cmos_data[RTC_REG_A] |= REG_A_UIP;
- }
- /* should be 244 us = 8 / 32768 seconds, but currently the
- timers do not have the necessary resolution. */
- delay = (ticks_per_sec * 1) / 100;
- if (delay < 1)
- delay = 1;
- qemu_mod_timer(s->second_timer2,
- s->next_second_time + delay);
- }
-}
-
-static void rtc_update_second2(void *opaque)
-{
- RTCState *s = opaque;
-
- if (!(s->cmos_data[RTC_REG_B] & REG_B_SET)) {
- rtc_copy_date(s);
- }
-
- /* check alarm */
- if (s->cmos_data[RTC_REG_B] & REG_B_AIE) {
- if (((s->cmos_data[RTC_SECONDS_ALARM] & 0xc0) == 0xc0 ||
- s->cmos_data[RTC_SECONDS_ALARM] == s->current_tm.tm_sec) &&
- ((s->cmos_data[RTC_MINUTES_ALARM] & 0xc0) == 0xc0 ||
- s->cmos_data[RTC_MINUTES_ALARM] == s->current_tm.tm_mon) &&
- ((s->cmos_data[RTC_HOURS_ALARM] & 0xc0) == 0xc0 ||
- s->cmos_data[RTC_HOURS_ALARM] == s->current_tm.tm_hour)) {
-
- s->cmos_data[RTC_REG_C] |= 0xa0;
- pic_set_irq(s->irq, 1);
- }
- }
-
- /* update ended interrupt */
- if (s->cmos_data[RTC_REG_B] & REG_B_UIE) {
- s->cmos_data[RTC_REG_C] |= 0x90;
- pic_set_irq(s->irq, 1);
- }
-
- /* clear update in progress bit */
- s->cmos_data[RTC_REG_A] &= ~REG_A_UIP;
-
- s->next_second_time += ticks_per_sec;
- qemu_mod_timer(s->second_timer, s->next_second_time);
-}
-
-static uint32_t cmos_ioport_read(void *opaque, uint32_t addr)
-{
- RTCState *s = opaque;
- int ret;
- if ((addr & 1) == 0) {
- return 0xff;
- } else {
- switch(s->cmos_index) {
- case RTC_SECONDS:
- case RTC_MINUTES:
- case RTC_HOURS:
- case RTC_DAY_OF_WEEK:
- case RTC_DAY_OF_MONTH:
- case RTC_MONTH:
- case RTC_YEAR:
- ret = s->cmos_data[s->cmos_index];
- break;
- case RTC_REG_A:
- ret = s->cmos_data[s->cmos_index];
- break;
- case RTC_REG_C:
- ret = s->cmos_data[s->cmos_index];
- pic_set_irq(s->irq, 0);
- s->cmos_data[RTC_REG_C] = 0x00;
- break;
- default:
- ret = s->cmos_data[s->cmos_index];
- break;
- }
-#ifdef DEBUG_CMOS
- printf("cmos: read index=0x%02x val=0x%02x\n",
- s->cmos_index, ret);
-#endif
- return ret;
- }
-}
-
-void rtc_set_memory(RTCState *s, int addr, int val)
-{
- if (addr >= 0 && addr <= 127)
- s->cmos_data[addr] = val;
-}
-
-void rtc_set_date(RTCState *s, const struct tm *tm)
-{
- s->current_tm = *tm;
- rtc_copy_date(s);
-}
-
-static void rtc_save(QEMUFile *f, void *opaque)
-{
- RTCState *s = opaque;
-
- qemu_put_buffer(f, s->cmos_data, 128);
- qemu_put_8s(f, &s->cmos_index);
-
- qemu_put_be32s(f, &s->current_tm.tm_sec);
- qemu_put_be32s(f, &s->current_tm.tm_min);
- qemu_put_be32s(f, &s->current_tm.tm_hour);
- qemu_put_be32s(f, &s->current_tm.tm_wday);
- qemu_put_be32s(f, &s->current_tm.tm_mday);
- qemu_put_be32s(f, &s->current_tm.tm_mon);
- qemu_put_be32s(f, &s->current_tm.tm_year);
-
- qemu_put_timer(f, s->periodic_timer);
- qemu_put_be64s(f, &s->next_periodic_time);
-
- qemu_put_be64s(f, &s->next_second_time);
- qemu_put_timer(f, s->second_timer);
- qemu_put_timer(f, s->second_timer2);
-}
-
-static int rtc_load(QEMUFile *f, void *opaque, int version_id)
-{
- RTCState *s = opaque;
-
- if (version_id != 1)
- return -EINVAL;
-
- qemu_get_buffer(f, s->cmos_data, 128);
- qemu_get_8s(f, &s->cmos_index);
-
- qemu_get_be32s(f, &s->current_tm.tm_sec);
- qemu_get_be32s(f, &s->current_tm.tm_min);
- qemu_get_be32s(f, &s->current_tm.tm_hour);
- qemu_get_be32s(f, &s->current_tm.tm_wday);
- qemu_get_be32s(f, &s->current_tm.tm_mday);
- qemu_get_be32s(f, &s->current_tm.tm_mon);
- qemu_get_be32s(f, &s->current_tm.tm_year);
-
- qemu_get_timer(f, s->periodic_timer);
- qemu_get_be64s(f, &s->next_periodic_time);
-
- qemu_get_be64s(f, &s->next_second_time);
- qemu_get_timer(f, s->second_timer);
- qemu_get_timer(f, s->second_timer2);
- return 0;
-}
-
-RTCState *rtc_init(int base, int irq)
-{
- RTCState *s;
-
- s = qemu_mallocz(sizeof(RTCState));
- if (!s)
- return NULL;
-
- s->irq = irq;
- s->cmos_data[RTC_REG_A] = 0x26;
- s->cmos_data[RTC_REG_B] = 0x02;
- s->cmos_data[RTC_REG_C] = 0x00;
- s->cmos_data[RTC_REG_D] = 0x80;
-
- s->periodic_timer = qemu_new_timer(vm_clock,
- rtc_periodic_timer, s);
- s->second_timer = qemu_new_timer(vm_clock,
- rtc_update_second, s);
- s->second_timer2 = qemu_new_timer(vm_clock,
- rtc_update_second2, s);
-
- s->next_second_time = qemu_get_clock(vm_clock) + (ticks_per_sec * 99) / 100;
- qemu_mod_timer(s->second_timer2, s->next_second_time);
-
- register_ioport_write(base, 2, 1, cmos_ioport_write, s);
- register_ioport_read(base, 2, 1, cmos_ioport_read, s);
-
- register_savevm("mc146818rtc", base, 1, rtc_save, rtc_load, s);
- return s;
-}
-
+++ /dev/null
-/*
- * QEMU NE2000 emulation
- *
- * Copyright (c) 2003-2004 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "vl.h"
-
-/* debug NE2000 card */
-//#define DEBUG_NE2000
-
-#define MAX_ETH_FRAME_SIZE 1514
-
-#define E8390_CMD 0x00 /* The command register (for all pages) */
-/* Page 0 register offsets. */
-#define EN0_CLDALO 0x01 /* Low byte of current local dma addr RD */
-#define EN0_STARTPG 0x01 /* Starting page of ring bfr WR */
-#define EN0_CLDAHI 0x02 /* High byte of current local dma addr RD */
-#define EN0_STOPPG 0x02 /* Ending page +1 of ring bfr WR */
-#define EN0_BOUNDARY 0x03 /* Boundary page of ring bfr RD WR */
-#define EN0_TSR 0x04 /* Transmit status reg RD */
-#define EN0_TPSR 0x04 /* Transmit starting page WR */
-#define EN0_NCR 0x05 /* Number of collision reg RD */
-#define EN0_TCNTLO 0x05 /* Low byte of tx byte count WR */
-#define EN0_FIFO 0x06 /* FIFO RD */
-#define EN0_TCNTHI 0x06 /* High byte of tx byte count WR */
-#define EN0_ISR 0x07 /* Interrupt status reg RD WR */
-#define EN0_CRDALO 0x08 /* low byte of current remote dma address RD */
-#define EN0_RSARLO 0x08 /* Remote start address reg 0 */
-#define EN0_CRDAHI 0x09 /* high byte, current remote dma address RD */
-#define EN0_RSARHI 0x09 /* Remote start address reg 1 */
-#define EN0_RCNTLO 0x0a /* Remote byte count reg WR */
-#define EN0_RCNTHI 0x0b /* Remote byte count reg WR */
-#define EN0_RSR 0x0c /* rx status reg RD */
-#define EN0_RXCR 0x0c /* RX configuration reg WR */
-#define EN0_TXCR 0x0d /* TX configuration reg WR */
-#define EN0_COUNTER0 0x0d /* Rcv alignment error counter RD */
-#define EN0_DCFG 0x0e /* Data configuration reg WR */
-#define EN0_COUNTER1 0x0e /* Rcv CRC error counter RD */
-#define EN0_IMR 0x0f /* Interrupt mask reg WR */
-#define EN0_COUNTER2 0x0f /* Rcv missed frame error counter RD */
-
-#define EN1_PHYS 0x11
-#define EN1_CURPAG 0x17
-#define EN1_MULT 0x18
-
-/* Register accessed at EN_CMD, the 8390 base addr. */
-#define E8390_STOP 0x01 /* Stop and reset the chip */
-#define E8390_START 0x02 /* Start the chip, clear reset */
-#define E8390_TRANS 0x04 /* Transmit a frame */
-#define E8390_RREAD 0x08 /* Remote read */
-#define E8390_RWRITE 0x10 /* Remote write */
-#define E8390_NODMA 0x20 /* Remote DMA */
-#define E8390_PAGE0 0x00 /* Select page chip registers */
-#define E8390_PAGE1 0x40 /* using the two high-order bits */
-#define E8390_PAGE2 0x80 /* Page 3 is invalid. */
-
-/* Bits in EN0_ISR - Interrupt status register */
-#define ENISR_RX 0x01 /* Receiver, no error */
-#define ENISR_TX 0x02 /* Transmitter, no error */
-#define ENISR_RX_ERR 0x04 /* Receiver, with error */
-#define ENISR_TX_ERR 0x08 /* Transmitter, with error */
-#define ENISR_OVER 0x10 /* Receiver overwrote the ring */
-#define ENISR_COUNTERS 0x20 /* Counters need emptying */
-#define ENISR_RDC 0x40 /* remote dma complete */
-#define ENISR_RESET 0x80 /* Reset completed */
-#define ENISR_ALL 0x3f /* Interrupts we will enable */
-
-/* Bits in received packet status byte and EN0_RSR*/
-#define ENRSR_RXOK 0x01 /* Received a good packet */
-#define ENRSR_CRC 0x02 /* CRC error */
-#define ENRSR_FAE 0x04 /* frame alignment error */
-#define ENRSR_FO 0x08 /* FIFO overrun */
-#define ENRSR_MPA 0x10 /* missed pkt */
-#define ENRSR_PHY 0x20 /* physical/multicast address */
-#define ENRSR_DIS 0x40 /* receiver disable. set in monitor mode */
-#define ENRSR_DEF 0x80 /* deferring */
-
-/* Transmitted packet status, EN0_TSR. */
-#define ENTSR_PTX 0x01 /* Packet transmitted without error */
-#define ENTSR_ND 0x02 /* The transmit wasn't deferred. */
-#define ENTSR_COL 0x04 /* The transmit collided at least once. */
-#define ENTSR_ABT 0x08 /* The transmit collided 16 times, and was deferred. */
-#define ENTSR_CRS 0x10 /* The carrier sense was lost. */
-#define ENTSR_FU 0x20 /* A "FIFO underrun" occurred during transmit. */
-#define ENTSR_CDH 0x40 /* The collision detect "heartbeat" signal was lost. */
-#define ENTSR_OWC 0x80 /* There was an out-of-window collision. */
-
-#define NE2000_PMEM_SIZE (32*1024)
-#define NE2000_PMEM_START (16*1024)
-#define NE2000_PMEM_END (NE2000_PMEM_SIZE+NE2000_PMEM_START)
-#define NE2000_MEM_SIZE NE2000_PMEM_END
-
-typedef struct NE2000State {
- uint8_t cmd;
- uint32_t start;
- uint32_t stop;
- uint8_t boundary;
- uint8_t tsr;
- uint8_t tpsr;
- uint16_t tcnt;
- uint16_t rcnt;
- uint32_t rsar;
- uint8_t rsr;
- uint8_t isr;
- uint8_t dcfg;
- uint8_t imr;
- uint8_t phys[6]; /* mac address */
- uint8_t curpag;
- uint8_t mult[8]; /* multicast mask array */
- int irq;
- PCIDevice *pci_dev;
- NetDriverState *nd;
- uint8_t mem[NE2000_MEM_SIZE];
-} NE2000State;
-
-static void ne2000_reset(NE2000State *s)
-{
- int i;
-
- s->isr = ENISR_RESET;
- memcpy(s->mem, s->nd->macaddr, 6);
- s->mem[14] = 0x57;
- s->mem[15] = 0x57;
-
- /* duplicate prom data */
- for(i = 15;i >= 0; i--) {
- s->mem[2 * i] = s->mem[i];
- s->mem[2 * i + 1] = s->mem[i];
- }
-}
-
-static int ne2000_buffer_full(NE2000State *s)
-{
- int avail, index, boundary;
-
- index = s->curpag << 8;
- boundary = s->boundary << 8;
- if (index <= boundary)
- /* when index == boundary, we should assume the
- * buffer is full instead of empty!
- */
- avail = boundary - index;
- else
- avail = (s->stop - s->start) - (index - boundary);
-
- return (avail < (MAX_ETH_FRAME_SIZE + 4));
-}
-
-static void ne2000_update_irq(NE2000State *s)
-{
- int isr;
-
- if (ne2000_buffer_full(s)) {
- /* The freeing space is not enough, tell the ne2k driver
- * to fetch these packets!
- */
- s->isr |= ENISR_RX;
- }
- isr = s->isr & s->imr;
-#if defined(DEBUG_NE2000)
- printf("NE2000: Set IRQ line %d to %d (%02x %02x)\n",
- s->irq, isr ? 1 : 0, s->isr, s->imr);
-#endif
- if (s->irq == 16) {
- /* PCI irq */
- pci_set_irq(s->pci_dev, 0, (isr != 0));
- } else {
- /* ISA irq */
- pic_set_irq(s->irq, (isr != 0));
- }
-}
-
-/* return the max buffer size if the NE2000 can receive more data */
-static int ne2000_can_receive(void *opaque)
-{
- NE2000State *s = opaque;
-
- if (s->cmd & E8390_STOP)
- return 0;
-
- return (ne2000_buffer_full(s) ? 0 : MAX_ETH_FRAME_SIZE);
-}
-
-#define MIN_BUF_SIZE 60
-
-static void ne2000_receive(void *opaque, const uint8_t *buf, int size)
-{
- NE2000State *s = opaque;
- uint8_t *p;
- int total_len, next, avail, len, index;
- uint8_t buf1[60];
-
-#if defined(DEBUG_NE2000)
- printf("NE2000: received len=%d\n", size);
-#endif
-
- /* if too small buffer, then expand it */
- if (size < MIN_BUF_SIZE) {
- memcpy(buf1, buf, size);
- memset(buf1 + size, 0, MIN_BUF_SIZE - size);
- buf = buf1;
- size = MIN_BUF_SIZE;
- }
-
- index = s->curpag << 8;
- /* 4 bytes for header */
- total_len = size + 4;
- /* address for next packet (4 bytes for CRC) */
- next = index + ((total_len + 4 + 255) & ~0xff);
- if (next >= s->stop)
- next -= (s->stop - s->start);
- /* prepare packet header */
- p = s->mem + index;
- s->rsr = ENRSR_RXOK; /* receive status */
- /* XXX: check this */
- if (buf[0] & 0x01)
- s->rsr |= ENRSR_PHY;
- p[0] = s->rsr;
- p[1] = next >> 8;
- p[2] = total_len;
- p[3] = total_len >> 8;
- index += 4;
-
- /* write packet data */
- while (size > 0) {
- avail = s->stop - index;
- len = size;
- if (len > avail)
- len = avail;
- memcpy(s->mem + index, buf, len);
- buf += len;
- index += len;
- if (index == s->stop)
- index = s->start;
- size -= len;
- }
- s->curpag = next >> 8;
-
- /* now we can signal we have receive something */
- s->isr |= ENISR_RX;
- ne2000_update_irq(s);
-}
-
-static void ne2000_ioport_write(void *opaque, uint32_t addr, uint32_t val)
-{
- NE2000State *s = opaque;
- int offset, page;
-
- addr &= 0xf;
-#ifdef DEBUG_NE2000
- printf("NE2000: write addr=0x%x val=0x%02x\n", addr, val);
-#endif
- if (addr == E8390_CMD) {
- /* control register */
- s->cmd = val;
- if (val & E8390_START) {
- s->isr &= ~ENISR_RESET;
- /* test specific case: zero length transfert */
- if ((val & (E8390_RREAD | E8390_RWRITE)) &&
- s->rcnt == 0) {
- s->isr |= ENISR_RDC;
- ne2000_update_irq(s);
- }
- if (val & E8390_TRANS) {
- qemu_send_packet(s->nd, s->mem + (s->tpsr << 8), s->tcnt);
- /* signal end of transfert */
- s->tsr = ENTSR_PTX;
- s->isr |= ENISR_TX;
- ne2000_update_irq(s);
- }
- }
- } else {
- page = s->cmd >> 6;
- offset = addr | (page << 4);
- switch(offset) {
- case EN0_STARTPG:
- s->start = val << 8;
- break;
- case EN0_STOPPG:
- s->stop = val << 8;
- break;
- case EN0_BOUNDARY:
- s->boundary = val;
- break;
- case EN0_IMR:
- s->imr = val;
- ne2000_update_irq(s);
- break;
- case EN0_TPSR:
- s->tpsr = val;
- break;
- case EN0_TCNTLO:
- s->tcnt = (s->tcnt & 0xff00) | val;
- break;
- case EN0_TCNTHI:
- s->tcnt = (s->tcnt & 0x00ff) | (val << 8);
- break;
- case EN0_RSARLO:
- s->rsar = (s->rsar & 0xff00) | val;
- break;
- case EN0_RSARHI:
- s->rsar = (s->rsar & 0x00ff) | (val << 8);
- break;
- case EN0_RCNTLO:
- s->rcnt = (s->rcnt & 0xff00) | val;
- break;
- case EN0_RCNTHI:
- s->rcnt = (s->rcnt & 0x00ff) | (val << 8);
- break;
- case EN0_DCFG:
- s->dcfg = val;
- break;
- case EN0_ISR:
- s->isr &= ~(val & 0x7f);
- ne2000_update_irq(s);
- break;
- case EN1_PHYS ... EN1_PHYS + 5:
- s->phys[offset - EN1_PHYS] = val;
- break;
- case EN1_CURPAG:
- s->curpag = val;
- break;
- case EN1_MULT ... EN1_MULT + 7:
- s->mult[offset - EN1_MULT] = val;
- break;
- }
- }
- update_select_wakeup_events();
-}
-
-static uint32_t ne2000_ioport_read(void *opaque, uint32_t addr)
-{
- NE2000State *s = opaque;
- int offset, page, ret;
-
- addr &= 0xf;
- if (addr == E8390_CMD) {
- ret = s->cmd;
- } else {
- page = s->cmd >> 6;
- offset = addr | (page << 4);
- switch(offset) {
- case EN0_TSR:
- ret = s->tsr;
- break;
- case EN0_BOUNDARY:
- ret = s->boundary;
- break;
- case EN0_ISR:
- ret = s->isr;
- break;
- case EN0_RSARLO:
- ret = s->rsar & 0x00ff;
- break;
- case EN0_RSARHI:
- ret = s->rsar >> 8;
- break;
- case EN1_PHYS ... EN1_PHYS + 5:
- ret = s->phys[offset - EN1_PHYS];
- break;
- case EN1_CURPAG:
- ret = s->curpag;
- break;
- case EN1_MULT ... EN1_MULT + 7:
- ret = s->mult[offset - EN1_MULT];
- break;
- case EN0_RSR:
- ret = s->rsr;
- break;
- default:
- ret = 0x00;
- break;
- }
- }
- update_select_wakeup_events();
-#ifdef DEBUG_NE2000
- printf("NE2000: read addr=0x%x val=%02x\n", addr, ret);
-#endif
- return ret;
-}
-
-static inline void ne2000_mem_writeb(NE2000State *s, uint32_t addr,
- uint32_t val)
-{
- if (addr < 32 ||
- (addr >= NE2000_PMEM_START && addr < NE2000_MEM_SIZE)) {
- s->mem[addr] = val;
- }
-}
-
-static inline void ne2000_mem_writew(NE2000State *s, uint32_t addr,
- uint32_t val)
-{
- addr &= ~1; /* XXX: check exact behaviour if not even */
- if (addr < 32 ||
- (addr >= NE2000_PMEM_START && addr < NE2000_MEM_SIZE)) {
- *(uint16_t *)(s->mem + addr) = cpu_to_le16(val);
- }
-}
-
-static inline void ne2000_mem_writel(NE2000State *s, uint32_t addr,
- uint32_t val)
-{
- addr &= ~1; /* XXX: check exact behaviour if not even */
- if (addr < 32 ||
- (addr >= NE2000_PMEM_START && addr < NE2000_MEM_SIZE)) {
- cpu_to_le32wu((uint32_t *)(s->mem + addr), val);
- }
-}
-
-static inline uint32_t ne2000_mem_readb(NE2000State *s, uint32_t addr)
-{
- if (addr < 32 ||
- (addr >= NE2000_PMEM_START && addr < NE2000_MEM_SIZE)) {
- return s->mem[addr];
- } else {
- return 0xff;
- }
-}
-
-static inline uint32_t ne2000_mem_readw(NE2000State *s, uint32_t addr)
-{
- addr &= ~1; /* XXX: check exact behaviour if not even */
- if (addr < 32 ||
- (addr >= NE2000_PMEM_START && addr < NE2000_MEM_SIZE)) {
- return le16_to_cpu(*(uint16_t *)(s->mem + addr));
- } else {
- return 0xffff;
- }
-}
-
-static inline uint32_t ne2000_mem_readl(NE2000State *s, uint32_t addr)
-{
- addr &= ~1; /* XXX: check exact behaviour if not even */
- if (addr < 32 ||
- (addr >= NE2000_PMEM_START && addr < NE2000_MEM_SIZE)) {
- return le32_to_cpupu((uint32_t *)(s->mem + addr));
- } else {
- return 0xffffffff;
- }
-}
-
-static inline void ne2000_dma_update(NE2000State *s, int len)
-{
- s->rsar += len;
- /* wrap */
- /* XXX: check what to do if rsar > stop */
- if (s->rsar == s->stop)
- s->rsar = s->start;
-
- if (s->rcnt <= len) {
- s->rcnt = 0;
- /* signal end of transfert */
- s->isr |= ENISR_RDC;
- ne2000_update_irq(s);
- } else {
- s->rcnt -= len;
- }
-}
-
-static void ne2000_asic_ioport_write(void *opaque, uint32_t addr, uint32_t val)
-{
- NE2000State *s = opaque;
-
-#ifdef DEBUG_NE2000
- printf("NE2000: asic write val=0x%04x\n", val);
-#endif
- if (s->rcnt == 0)
- return;
- if (s->dcfg & 0x01) {
- /* 16 bit access */
- ne2000_mem_writew(s, s->rsar, val);
- ne2000_dma_update(s, 2);
- } else {
- /* 8 bit access */
- ne2000_mem_writeb(s, s->rsar, val);
- ne2000_dma_update(s, 1);
- }
- update_select_wakeup_events();
-}
-
-static uint32_t ne2000_asic_ioport_read(void *opaque, uint32_t addr)
-{
- NE2000State *s = opaque;
- int ret;
-
- if (s->dcfg & 0x01) {
- /* 16 bit access */
- ret = ne2000_mem_readw(s, s->rsar);
- ne2000_dma_update(s, 2);
- } else {
- /* 8 bit access */
- ret = ne2000_mem_readb(s, s->rsar);
- ne2000_dma_update(s, 1);
- }
- update_select_wakeup_events();
-#ifdef DEBUG_NE2000
- printf("NE2000: asic read val=0x%04x\n", ret);
-#endif
- return ret;
-}
-
-static void ne2000_asic_ioport_writel(void *opaque, uint32_t addr, uint32_t val)
-{
- NE2000State *s = opaque;
-
-#ifdef DEBUG_NE2000
- printf("NE2000: asic writel val=0x%04x\n", val);
-#endif
- if (s->rcnt == 0)
- return;
- /* 32 bit access */
- ne2000_mem_writel(s, s->rsar, val);
- ne2000_dma_update(s, 4);
- update_select_wakeup_events();
-}
-
-static uint32_t ne2000_asic_ioport_readl(void *opaque, uint32_t addr)
-{
- NE2000State *s = opaque;
- int ret;
-
- /* 32 bit access */
- ret = ne2000_mem_readl(s, s->rsar);
- ne2000_dma_update(s, 4);
- update_select_wakeup_events();
-#ifdef DEBUG_NE2000
- printf("NE2000: asic readl val=0x%04x\n", ret);
-#endif
- return ret;
-}
-
-static void ne2000_reset_ioport_write(void *opaque, uint32_t addr, uint32_t val)
-{
- /* nothing to do (end of reset pulse) */
-}
-
-static uint32_t ne2000_reset_ioport_read(void *opaque, uint32_t addr)
-{
- NE2000State *s = opaque;
- ne2000_reset(s);
- update_select_wakeup_events();
- return 0;
-}
-
-static void ne2000_save(QEMUFile* f,void* opaque)
-{
- NE2000State* s=(NE2000State*)opaque;
-
- qemu_put_8s(f, &s->cmd);
- qemu_put_be32s(f, &s->start);
- qemu_put_be32s(f, &s->stop);
- qemu_put_8s(f, &s->boundary);
- qemu_put_8s(f, &s->tsr);
- qemu_put_8s(f, &s->tpsr);
- qemu_put_be16s(f, &s->tcnt);
- qemu_put_be16s(f, &s->rcnt);
- qemu_put_be32s(f, &s->rsar);
- qemu_put_8s(f, &s->rsr);
- qemu_put_8s(f, &s->isr);
- qemu_put_8s(f, &s->dcfg);
- qemu_put_8s(f, &s->imr);
- qemu_put_buffer(f, s->phys, 6);
- qemu_put_8s(f, &s->curpag);
- qemu_put_buffer(f, s->mult, 8);
- qemu_put_be32s(f, &s->irq);
- qemu_put_buffer(f, s->mem, NE2000_MEM_SIZE);
-}
-
-static int ne2000_load(QEMUFile* f,void* opaque,int version_id)
-{
- NE2000State* s=(NE2000State*)opaque;
-
- if (version_id != 1)
- return -EINVAL;
-
- qemu_get_8s(f, &s->cmd);
- qemu_get_be32s(f, &s->start);
- qemu_get_be32s(f, &s->stop);
- qemu_get_8s(f, &s->boundary);
- qemu_get_8s(f, &s->tsr);
- qemu_get_8s(f, &s->tpsr);
- qemu_get_be16s(f, &s->tcnt);
- qemu_get_be16s(f, &s->rcnt);
- qemu_get_be32s(f, &s->rsar);
- qemu_get_8s(f, &s->rsr);
- qemu_get_8s(f, &s->isr);
- qemu_get_8s(f, &s->dcfg);
- qemu_get_8s(f, &s->imr);
- qemu_get_buffer(f, s->phys, 6);
- qemu_get_8s(f, &s->curpag);
- qemu_get_buffer(f, s->mult, 8);
- qemu_get_be32s(f, &s->irq);
- qemu_get_buffer(f, s->mem, NE2000_MEM_SIZE);
-
- return 0;
-}
-
-void isa_ne2000_init(int base, int irq, NetDriverState *nd)
-{
- NE2000State *s;
-
- s = qemu_mallocz(sizeof(NE2000State));
- if (!s)
- return;
-
- register_ioport_write(base, 16, 1, ne2000_ioport_write, s);
- register_ioport_read(base, 16, 1, ne2000_ioport_read, s);
-
- register_ioport_write(base + 0x10, 1, 1, ne2000_asic_ioport_write, s);
- register_ioport_read(base + 0x10, 1, 1, ne2000_asic_ioport_read, s);
- register_ioport_write(base + 0x10, 2, 2, ne2000_asic_ioport_write, s);
- register_ioport_read(base + 0x10, 2, 2, ne2000_asic_ioport_read, s);
-
- register_ioport_write(base + 0x1f, 1, 1, ne2000_reset_ioport_write, s);
- register_ioport_read(base + 0x1f, 1, 1, ne2000_reset_ioport_read, s);
- s->irq = irq;
- s->nd = nd;
-
- ne2000_reset(s);
-
- qemu_add_read_packet(nd, ne2000_can_receive, ne2000_receive, s);
-
- register_savevm("ne2000", 0, 1, ne2000_save, ne2000_load, s);
-
-}
-
-/***********************************************************/
-/* PCI NE2000 definitions */
-
-typedef struct PCINE2000State {
- PCIDevice dev;
- NE2000State ne2000;
-} PCINE2000State;
-
-static void ne2000_map(PCIDevice *pci_dev, int region_num,
- uint32_t addr, uint32_t size, int type)
-{
- PCINE2000State *d = (PCINE2000State *)pci_dev;
- NE2000State *s = &d->ne2000;
-
- register_ioport_write(addr, 16, 1, ne2000_ioport_write, s);
- register_ioport_read(addr, 16, 1, ne2000_ioport_read, s);
-
- register_ioport_write(addr + 0x10, 1, 1, ne2000_asic_ioport_write, s);
- register_ioport_read(addr + 0x10, 1, 1, ne2000_asic_ioport_read, s);
- register_ioport_write(addr + 0x10, 2, 2, ne2000_asic_ioport_write, s);
- register_ioport_read(addr + 0x10, 2, 2, ne2000_asic_ioport_read, s);
- register_ioport_write(addr + 0x10, 4, 4, ne2000_asic_ioport_writel, s);
- register_ioport_read(addr + 0x10, 4, 4, ne2000_asic_ioport_readl, s);
-
- register_ioport_write(addr + 0x1f, 1, 1, ne2000_reset_ioport_write, s);
- register_ioport_read(addr + 0x1f, 1, 1, ne2000_reset_ioport_read, s);
-}
-
-void pci_ne2000_init(PCIBus *bus, NetDriverState *nd)
-{
- PCINE2000State *d;
- NE2000State *s;
- uint8_t *pci_conf;
-
- d = (PCINE2000State *)pci_register_device(bus,
- "NE2000", sizeof(PCINE2000State),
- -1,
- NULL, NULL);
- pci_conf = d->dev.config;
- pci_conf[0x00] = 0xec; // Realtek 8029
- pci_conf[0x01] = 0x10;
- pci_conf[0x02] = 0x29;
- pci_conf[0x03] = 0x80;
- pci_conf[0x0a] = 0x00; // ethernet network controller
- pci_conf[0x0b] = 0x02;
- pci_conf[0x0e] = 0x00; // header_type
- pci_conf[0x3d] = 1; // interrupt pin 0
-
- pci_register_io_region(&d->dev, 0, 0x100,
- PCI_ADDRESS_SPACE_IO, ne2000_map);
- s = &d->ne2000;
- s->irq = 16; // PCI interrupt
- s->pci_dev = (PCIDevice *)d;
- s->nd = nd;
- ne2000_reset(s);
- qemu_add_read_packet(nd, ne2000_can_receive, ne2000_receive, s);
-
- /* XXX: instance number ? */
- register_savevm("ne2000", 0, 1, ne2000_save, ne2000_load, s);
- register_savevm("ne2000_pci", 0, 1, generic_pci_save, generic_pci_load,
- &d->dev);
-}
+++ /dev/null
-/*
- * OpenPIC emulation
- *
- * Copyright (c) 2004 Jocelyn Mayer
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-/*
- *
- * Based on OpenPic implementations:
- * - Intel GW80314 I/O compagnion chip developper's manual
- * - Motorola MPC8245 & MPC8540 user manuals.
- * - Motorola MCP750 (aka Raven) programmer manual.
- * - Motorola Harrier programmer manuel
- *
- * Serial interrupts, as implemented in Raven chipset are not supported yet.
- *
- */
-#include "vl.h"
-
-//#define DEBUG_OPENPIC
-
-#ifdef DEBUG_OPENPIC
-#define DPRINTF(fmt, args...) do { printf(fmt , ##args); } while (0)
-#else
-#define DPRINTF(fmt, args...) do { } while (0)
-#endif
-#define ERROR(fmr, args...) do { printf("ERROR: " fmr , ##args); } while (0)
-
-#define USE_MPCxxx /* Intel model is broken, for now */
-
-#if defined (USE_INTEL_GW80314)
-/* Intel GW80314 I/O Companion chip */
-
-#define MAX_CPU 4
-#define MAX_IRQ 32
-#define MAX_DBL 4
-#define MAX_MBX 4
-#define MAX_TMR 4
-#define VECTOR_BITS 8
-#define MAX_IPI 0
-
-#define VID (0x00000000)
-
-#define OPENPIC_LITTLE_ENDIAN 1
-#define OPENPIC_BIG_ENDIAN 0
-
-#elif defined(USE_MPCxxx)
-
-#define MAX_CPU 2
-#define MAX_IRQ 64
-#define EXT_IRQ 48
-#define MAX_DBL 0
-#define MAX_MBX 0
-#define MAX_TMR 4
-#define VECTOR_BITS 8
-#define MAX_IPI 4
-#define VID 0x03 /* MPIC version ID */
-#define VENI 0x00000000 /* Vendor ID */
-
-enum {
- IRQ_IPVP = 0,
- IRQ_IDE,
-};
-
-#define OPENPIC_LITTLE_ENDIAN 1
-#define OPENPIC_BIG_ENDIAN 0
-
-#else
-#error "Please select which OpenPic implementation is to be emulated"
-#endif
-
-#if (OPENPIC_BIG_ENDIAN && !TARGET_WORDS_BIGENDIAN) || \
- (OPENPIC_LITTLE_ENDIAN && TARGET_WORDS_BIGENDIAN)
-#define OPENPIC_SWAP
-#endif
-
-/* Interrupt definitions */
-#define IRQ_FE (EXT_IRQ) /* Internal functional IRQ */
-#define IRQ_ERR (EXT_IRQ + 1) /* Error IRQ */
-#define IRQ_TIM0 (EXT_IRQ + 2) /* First timer IRQ */
-#if MAX_IPI > 0
-#define IRQ_IPI0 (IRQ_TIM0 + MAX_TMR) /* First IPI IRQ */
-#define IRQ_DBL0 (IRQ_IPI0 + (MAX_CPU * MAX_IPI)) /* First doorbell IRQ */
-#else
-#define IRQ_DBL0 (IRQ_TIM0 + MAX_TMR) /* First doorbell IRQ */
-#define IRQ_MBX0 (IRQ_DBL0 + MAX_DBL) /* First mailbox IRQ */
-#endif
-
-#define BF_WIDTH(_bits_) \
-(((_bits_) + (sizeof(uint32_t) * 8) - 1) / (sizeof(uint32_t) * 8))
-
-static inline void set_bit (uint32_t *field, int bit)
-{
- field[bit >> 5] |= 1 << (bit & 0x1F);
-}
-
-static inline void reset_bit (uint32_t *field, int bit)
-{
- field[bit >> 5] &= ~(1 << (bit & 0x1F));
-}
-
-static inline int test_bit (uint32_t *field, int bit)
-{
- return (field[bit >> 5] & 1 << (bit & 0x1F)) != 0;
-}
-
-enum {
- IRQ_EXTERNAL = 0x01,
- IRQ_INTERNAL = 0x02,
- IRQ_TIMER = 0x04,
- IRQ_SPECIAL = 0x08,
-} IRQ_src_type;
-
-typedef struct IRQ_queue_t {
- uint32_t queue[BF_WIDTH(MAX_IRQ)];
- int next;
- int priority;
-} IRQ_queue_t;
-
-typedef struct IRQ_src_t {
- uint32_t ipvp; /* IRQ vector/priority register */
- uint32_t ide; /* IRQ destination register */
- int type;
- int last_cpu;
- int pending; /* TRUE if IRQ is pending */
-} IRQ_src_t;
-
-enum IPVP_bits {
- IPVP_MASK = 31,
- IPVP_ACTIVITY = 30,
- IPVP_MODE = 29,
- IPVP_POLARITY = 23,
- IPVP_SENSE = 22,
-};
-#define IPVP_PRIORITY_MASK (0x1F << 16)
-#define IPVP_PRIORITY(_ipvpr_) ((int)(((_ipvpr_) & IPVP_PRIORITY_MASK) >> 16))
-#define IPVP_VECTOR_MASK ((1 << VECTOR_BITS) - 1)
-#define IPVP_VECTOR(_ipvpr_) ((_ipvpr_) & IPVP_VECTOR_MASK)
-
-typedef struct IRQ_dst_t {
- uint32_t pctp; /* CPU current task priority */
- uint32_t pcsr; /* CPU sensitivity register */
- IRQ_queue_t raised;
- IRQ_queue_t servicing;
- CPUState *env; /* Needed if we did SMP */
-} IRQ_dst_t;
-
-struct openpic_t {
- PCIDevice pci_dev;
- int mem_index;
- /* Global registers */
- uint32_t frep; /* Feature reporting register */
- uint32_t glbc; /* Global configuration register */
- uint32_t micr; /* MPIC interrupt configuration register */
- uint32_t veni; /* Vendor identification register */
- uint32_t spve; /* Spurious vector register */
- uint32_t tifr; /* Timer frequency reporting register */
- /* Source registers */
- IRQ_src_t src[MAX_IRQ];
- /* Local registers per output pin */
- IRQ_dst_t dst[MAX_CPU];
- int nb_cpus;
- /* Timer registers */
- struct {
- uint32_t ticc; /* Global timer current count register */
- uint32_t tibc; /* Global timer base count register */
- } timers[MAX_TMR];
-#if MAX_DBL > 0
- /* Doorbell registers */
- uint32_t dar; /* Doorbell activate register */
- struct {
- uint32_t dmr; /* Doorbell messaging register */
- } doorbells[MAX_DBL];
-#endif
-#if MAX_MBX > 0
- /* Mailbox registers */
- struct {
- uint32_t mbr; /* Mailbox register */
- } mailboxes[MAX_MAILBOXES];
-#endif
-};
-
-static inline void IRQ_setbit (IRQ_queue_t *q, int n_IRQ)
-{
- set_bit(q->queue, n_IRQ);
-}
-
-static inline void IRQ_resetbit (IRQ_queue_t *q, int n_IRQ)
-{
- reset_bit(q->queue, n_IRQ);
-}
-
-static inline int IRQ_testbit (IRQ_queue_t *q, int n_IRQ)
-{
- return test_bit(q->queue, n_IRQ);
-}
-
-static void IRQ_check (openpic_t *opp, IRQ_queue_t *q)
-{
- int next, i;
- int priority;
-
- next = -1;
- priority = -1;
- for (i = 0; i < MAX_IRQ; i++) {
- if (IRQ_testbit(q, i)) {
- DPRINTF("IRQ_check: irq %d set ipvp_pr=%d pr=%d\n",
- i, IPVP_PRIORITY(opp->src[i].ipvp), priority);
- if (IPVP_PRIORITY(opp->src[i].ipvp) > priority) {
- next = i;
- priority = IPVP_PRIORITY(opp->src[i].ipvp);
- }
- }
- }
- q->next = next;
- q->priority = priority;
-}
-
-static int IRQ_get_next (openpic_t *opp, IRQ_queue_t *q)
-{
- if (q->next == -1) {
- /* XXX: optimize */
- IRQ_check(opp, q);
- }
-
- return q->next;
-}
-
-static void IRQ_local_pipe (openpic_t *opp, int n_CPU, int n_IRQ)
-{
- IRQ_dst_t *dst;
- IRQ_src_t *src;
- int priority;
-
- dst = &opp->dst[n_CPU];
- src = &opp->src[n_IRQ];
- priority = IPVP_PRIORITY(src->ipvp);
- if (priority <= dst->pctp) {
- /* Too low priority */
- return;
- }
- if (IRQ_testbit(&dst->raised, n_IRQ)) {
- /* Interrupt miss */
- return;
- }
- set_bit(&src->ipvp, IPVP_ACTIVITY);
- IRQ_setbit(&dst->raised, n_IRQ);
- if (priority > dst->raised.priority) {
- IRQ_get_next(opp, &dst->raised);
- DPRINTF("Raise CPU IRQ\n");
- cpu_interrupt(cpu_single_env, CPU_INTERRUPT_HARD);
- }
-}
-
-/* update pic state because registers for n_IRQ have changed value */
-static void openpic_update_irq(openpic_t *opp, int n_IRQ)
-{
- IRQ_src_t *src;
- int i;
-
- src = &opp->src[n_IRQ];
-
- if (!src->pending) {
- /* no irq pending */
- return;
- }
- if (test_bit(&src->ipvp, IPVP_MASK)) {
- /* Interrupt source is disabled */
- return;
- }
- if (IPVP_PRIORITY(src->ipvp) == 0) {
- /* Priority set to zero */
- return;
- }
- if (test_bit(&src->ipvp, IPVP_ACTIVITY)) {
- /* IRQ already active */
- return;
- }
- if (src->ide == 0x00000000) {
- /* No target */
- return;
- }
-
- if (!test_bit(&src->ipvp, IPVP_MODE) ||
- src->ide == (1 << src->last_cpu)) {
- /* Directed delivery mode */
- for (i = 0; i < opp->nb_cpus; i++) {
- if (test_bit(&src->ide, i))
- IRQ_local_pipe(opp, i, n_IRQ);
- }
- } else {
- /* Distributed delivery mode */
- /* XXX: incorrect code */
- for (i = src->last_cpu; i < src->last_cpu; i++) {
- if (i == MAX_IRQ)
- i = 0;
- if (test_bit(&src->ide, i)) {
- IRQ_local_pipe(opp, i, n_IRQ);
- src->last_cpu = i;
- break;
- }
- }
- }
-}
-
-void openpic_set_irq(openpic_t *opp, int n_IRQ, int level)
-{
- IRQ_src_t *src;
-
- src = &opp->src[n_IRQ];
- DPRINTF("openpic: set irq %d = %d ipvp=%08x\n",
- n_IRQ, level, src->ipvp);
- if (test_bit(&src->ipvp, IPVP_SENSE)) {
- /* level-sensitive irq */
- src->pending = level;
- if (!level)
- reset_bit(&src->ipvp, IPVP_ACTIVITY);
- } else {
- /* edge-sensitive irq */
- if (level)
- src->pending = 1;
- }
- openpic_update_irq(opp, n_IRQ);
-}
-
-static void openpic_reset (openpic_t *opp)
-{
- int i;
-
- opp->glbc = 0x80000000;
- /* Initialise controler registers */
- opp->frep = ((EXT_IRQ - 1) << 16) | ((MAX_CPU - 1) << 8) | VID;
- opp->veni = VENI;
- opp->spve = 0x000000FF;
- opp->tifr = 0x003F7A00;
- /* ? */
- opp->micr = 0x00000000;
- /* Initialise IRQ sources */
- for (i = 0; i < MAX_IRQ; i++) {
- opp->src[i].ipvp = 0xA0000000;
- opp->src[i].ide = 0x00000000;
- }
- /* Initialise IRQ destinations */
- for (i = 0; i < opp->nb_cpus; i++) {
- opp->dst[i].pctp = 0x0000000F;
- opp->dst[i].pcsr = 0x00000000;
- memset(&opp->dst[i].raised, 0, sizeof(IRQ_queue_t));
- memset(&opp->dst[i].servicing, 0, sizeof(IRQ_queue_t));
- }
- /* Initialise timers */
- for (i = 0; i < MAX_TMR; i++) {
- opp->timers[i].ticc = 0x00000000;
- opp->timers[i].tibc = 0x80000000;
- }
- /* Initialise doorbells */
-#if MAX_DBL > 0
- opp->dar = 0x00000000;
- for (i = 0; i < MAX_DBL; i++) {
- opp->doorbells[i].dmr = 0x00000000;
- }
-#endif
- /* Initialise mailboxes */
-#if MAX_MBX > 0
- for (i = 0; i < MAX_MBX; i++) { /* ? */
- opp->mailboxes[i].mbr = 0x00000000;
- }
-#endif
- /* Go out of RESET state */
- opp->glbc = 0x00000000;
-}
-
-static inline uint32_t read_IRQreg (openpic_t *opp, int n_IRQ, uint32_t reg)
-{
- uint32_t retval;
-
- switch (reg) {
- case IRQ_IPVP:
- retval = opp->src[n_IRQ].ipvp;
- break;
- case IRQ_IDE:
- retval = opp->src[n_IRQ].ide;
- break;
- }
-
- return retval;
-}
-
-static inline void write_IRQreg (openpic_t *opp, int n_IRQ,
- uint32_t reg, uint32_t val)
-{
- uint32_t tmp;
-
- switch (reg) {
- case IRQ_IPVP:
- /* NOTE: not fully accurate for special IRQs, but simple and
- sufficient */
- /* ACTIVITY bit is read-only */
- opp->src[n_IRQ].ipvp =
- (opp->src[n_IRQ].ipvp & 0x40000000) |
- (val & 0x800F00FF);
- openpic_update_irq(opp, n_IRQ);
- DPRINTF("Set IPVP %d to 0x%08x -> 0x%08x\n",
- n_IRQ, val, opp->src[n_IRQ].ipvp);
- break;
- case IRQ_IDE:
- tmp = val & 0xC0000000;
- tmp |= val & ((1 << MAX_CPU) - 1);
- opp->src[n_IRQ].ide = tmp;
- DPRINTF("Set IDE %d to 0x%08x\n", n_IRQ, opp->src[n_IRQ].ide);
- break;
- }
-}
-
-#if 0 // Code provision for Intel model
-#if MAX_DBL > 0
-static uint32_t read_doorbell_register (openpic_t *opp,
- int n_dbl, uint32_t offset)
-{
- uint32_t retval;
-
- switch (offset) {
- case DBL_IPVP_OFFSET:
- retval = read_IRQreg(opp, IRQ_DBL0 + n_dbl, IRQ_IPVP);
- break;
- case DBL_IDE_OFFSET:
- retval = read_IRQreg(opp, IRQ_DBL0 + n_dbl, IRQ_IDE);
- break;
- case DBL_DMR_OFFSET:
- retval = opp->doorbells[n_dbl].dmr;
- break;
- }
-
- return retval;
-}
-
-static void write_doorbell_register (penpic_t *opp, int n_dbl,
- uint32_t offset, uint32_t value)
-{
- switch (offset) {
- case DBL_IVPR_OFFSET:
- write_IRQreg(opp, IRQ_DBL0 + n_dbl, IRQ_IPVP, value);
- break;
- case DBL_IDE_OFFSET:
- write_IRQreg(opp, IRQ_DBL0 + n_dbl, IRQ_IDE, value);
- break;
- case DBL_DMR_OFFSET:
- opp->doorbells[n_dbl].dmr = value;
- break;
- }
-}
-#endif
-
-#if MAX_MBX > 0
-static uint32_t read_mailbox_register (openpic_t *opp,
- int n_mbx, uint32_t offset)
-{
- uint32_t retval;
-
- switch (offset) {
- case MBX_MBR_OFFSET:
- retval = opp->mailboxes[n_mbx].mbr;
- break;
- case MBX_IVPR_OFFSET:
- retval = read_IRQreg(opp, IRQ_MBX0 + n_mbx, IRQ_IPVP);
- break;
- case MBX_DMR_OFFSET:
- retval = read_IRQreg(opp, IRQ_MBX0 + n_mbx, IRQ_IDE);
- break;
- }
-
- return retval;
-}
-
-static void write_mailbox_register (openpic_t *opp, int n_mbx,
- uint32_t address, uint32_t value)
-{
- switch (offset) {
- case MBX_MBR_OFFSET:
- opp->mailboxes[n_mbx].mbr = value;
- break;
- case MBX_IVPR_OFFSET:
- write_IRQreg(opp, IRQ_MBX0 + n_mbx, IRQ_IPVP, value);
- break;
- case MBX_DMR_OFFSET:
- write_IRQreg(opp, IRQ_MBX0 + n_mbx, IRQ_IDE, value);
- break;
- }
-}
-#endif
-#endif /* 0 : Code provision for Intel model */
-
-static void openpic_gbl_write (void *opaque, uint32_t addr, uint32_t val)
-{
- openpic_t *opp = opaque;
-
- DPRINTF("%s: addr %08x <= %08x\n", __func__, addr, val);
- if (addr & 0xF)
- return;
-#if defined OPENPIC_SWAP
- val = bswap32(val);
-#endif
- addr &= 0xFF;
- switch (addr) {
- case 0x00: /* FREP */
- break;
- case 0x20: /* GLBC */
- if (val & 0x80000000)
- openpic_reset(opp);
- opp->glbc = val & ~0x80000000;
- break;
- case 0x80: /* VENI */
- break;
- case 0x90: /* PINT */
- /* XXX: Should be able to reset any CPU */
- if (val & 1) {
- DPRINTF("Reset CPU IRQ\n");
- // cpu_interrupt(cpu_single_env, CPU_INTERRUPT_RESET);
- }
- break;
-#if MAX_IPI > 0
- case 0xA0: /* IPI_IPVP */
- case 0xB0:
- case 0xC0:
- case 0xD0:
- {
- int idx;
- idx = (addr - 0xA0) >> 4;
- write_IRQreg(opp, IRQ_IPI0 + idx, IRQ_IPVP, val);
- }
- break;
-#endif
- case 0xE0: /* SPVE */
- opp->spve = val & 0x000000FF;
- break;
- case 0xF0: /* TIFR */
- opp->tifr = val;
- break;
- default:
- break;
- }
-}
-
-static uint32_t openpic_gbl_read (void *opaque, uint32_t addr)
-{
- openpic_t *opp = opaque;
- uint32_t retval;
-
- DPRINTF("%s: addr %08x\n", __func__, addr);
- retval = 0xFFFFFFFF;
- if (addr & 0xF)
- return retval;
- addr &= 0xFF;
- switch (addr) {
- case 0x00: /* FREP */
- retval = opp->frep;
- break;
- case 0x20: /* GLBC */
- retval = opp->glbc;
- break;
- case 0x80: /* VENI */
- retval = opp->veni;
- break;
- case 0x90: /* PINT */
- retval = 0x00000000;
- break;
-#if MAX_IPI > 0
- case 0xA0: /* IPI_IPVP */
- case 0xB0:
- case 0xC0:
- case 0xD0:
- {
- int idx;
- idx = (addr - 0xA0) >> 4;
- retval = read_IRQreg(opp, IRQ_IPI0 + idx, IRQ_IPVP);
- }
- break;
-#endif
- case 0xE0: /* SPVE */
- retval = opp->spve;
- break;
- case 0xF0: /* TIFR */
- retval = opp->tifr;
- break;
- default:
- break;
- }
- DPRINTF("%s: => %08x\n", __func__, retval);
-#if defined OPENPIC_SWAP
- retval = bswap32(retval);
-#endif
-
- return retval;
-}
-
-static void openpic_timer_write (void *opaque, uint32_t addr, uint32_t val)
-{
- openpic_t *opp = opaque;
- int idx;
-
- DPRINTF("%s: addr %08x <= %08x\n", __func__, addr, val);
- if (addr & 0xF)
- return;
-#if defined OPENPIC_SWAP
- val = bswap32(val);
-#endif
- addr -= 0x1100;
- addr &= 0xFFFF;
- idx = (addr & 0xFFF0) >> 6;
- addr = addr & 0x30;
- switch (addr) {
- case 0x00: /* TICC */
- break;
- case 0x10: /* TIBC */
- if ((opp->timers[idx].ticc & 0x80000000) != 0 &&
- (val & 0x800000000) == 0 &&
- (opp->timers[idx].tibc & 0x80000000) != 0)
- opp->timers[idx].ticc &= ~0x80000000;
- opp->timers[idx].tibc = val;
- break;
- case 0x20: /* TIVP */
- write_IRQreg(opp, IRQ_TIM0 + idx, IRQ_IPVP, val);
- break;
- case 0x30: /* TIDE */
- write_IRQreg(opp, IRQ_TIM0 + idx, IRQ_IDE, val);
- break;
- }
-}
-
-static uint32_t openpic_timer_read (void *opaque, uint32_t addr)
-{
- openpic_t *opp = opaque;
- uint32_t retval;
- int idx;
-
- DPRINTF("%s: addr %08x\n", __func__, addr);
- retval = 0xFFFFFFFF;
- if (addr & 0xF)
- return retval;
- addr -= 0x1100;
- addr &= 0xFFFF;
- idx = (addr & 0xFFF0) >> 6;
- addr = addr & 0x30;
- switch (addr) {
- case 0x00: /* TICC */
- retval = opp->timers[idx].ticc;
- break;
- case 0x10: /* TIBC */
- retval = opp->timers[idx].tibc;
- break;
- case 0x20: /* TIPV */
- retval = read_IRQreg(opp, IRQ_TIM0 + idx, IRQ_IPVP);
- break;
- case 0x30: /* TIDE */
- retval = read_IRQreg(opp, IRQ_TIM0 + idx, IRQ_IDE);
- break;
- }
- DPRINTF("%s: => %08x\n", __func__, retval);
-#if defined OPENPIC_SWAP
- retval = bswap32(retval);
-#endif
-
- return retval;
-}
-
-static void openpic_src_write (void *opaque, uint32_t addr, uint32_t val)
-{
- openpic_t *opp = opaque;
- int idx;
-
- DPRINTF("%s: addr %08x <= %08x\n", __func__, addr, val);
- if (addr & 0xF)
- return;
-#if defined OPENPIC_SWAP
- val = tswap32(val);
-#endif
- addr = addr & 0xFFF0;
- idx = addr >> 5;
- if (addr & 0x10) {
- /* EXDE / IFEDE / IEEDE */
- write_IRQreg(opp, idx, IRQ_IDE, val);
- } else {
- /* EXVP / IFEVP / IEEVP */
- write_IRQreg(opp, idx, IRQ_IPVP, val);
- }
-}
-
-static uint32_t openpic_src_read (void *opaque, uint32_t addr)
-{
- openpic_t *opp = opaque;
- uint32_t retval;
- int idx;
-
- DPRINTF("%s: addr %08x\n", __func__, addr);
- retval = 0xFFFFFFFF;
- if (addr & 0xF)
- return retval;
- addr = addr & 0xFFF0;
- idx = addr >> 5;
- if (addr & 0x10) {
- /* EXDE / IFEDE / IEEDE */
- retval = read_IRQreg(opp, idx, IRQ_IDE);
- } else {
- /* EXVP / IFEVP / IEEVP */
- retval = read_IRQreg(opp, idx, IRQ_IPVP);
- }
- DPRINTF("%s: => %08x\n", __func__, retval);
-#if defined OPENPIC_SWAP
- retval = tswap32(retval);
-#endif
-
- return retval;
-}
-
-static void openpic_cpu_write (void *opaque, uint32_t addr, uint32_t val)
-{
- openpic_t *opp = opaque;
- IRQ_src_t *src;
- IRQ_dst_t *dst;
- int idx, n_IRQ;
-
- DPRINTF("%s: addr %08x <= %08x\n", __func__, addr, val);
- if (addr & 0xF)
- return;
-#if defined OPENPIC_SWAP
- val = bswap32(val);
-#endif
- addr &= 0x1FFF0;
- idx = addr / 0x1000;
- dst = &opp->dst[idx];
- addr &= 0xFF0;
- switch (addr) {
-#if MAX_IPI > 0
- case 0x40: /* PIPD */
- case 0x50:
- case 0x60:
- case 0x70:
- idx = (addr - 0x40) >> 4;
- write_IRQreg(opp, IRQ_IPI0 + idx, IRQ_IDE, val);
- openpic_set_irq(opp, IRQ_IPI0 + idx, 1);
- openpic_set_irq(opp, IRQ_IPI0 + idx, 0);
- break;
-#endif
- case 0x80: /* PCTP */
- dst->pctp = val & 0x0000000F;
- break;
- case 0x90: /* WHOAMI */
- /* Read-only register */
- break;
- case 0xA0: /* PIAC */
- /* Read-only register */
- break;
- case 0xB0: /* PEOI */
- DPRINTF("PEOI\n");
- n_IRQ = IRQ_get_next(opp, &dst->servicing);
- IRQ_resetbit(&dst->servicing, n_IRQ);
- dst->servicing.next = -1;
- src = &opp->src[n_IRQ];
- /* Set up next servicing IRQ */
- IRQ_get_next(opp, &dst->servicing);
- /* Check queued interrupts. */
- n_IRQ = IRQ_get_next(opp, &dst->raised);
- if (n_IRQ != -1) {
- src = &opp->src[n_IRQ];
- if (IPVP_PRIORITY(src->ipvp) > dst->servicing.priority) {
- DPRINTF("Raise CPU IRQ\n");
- cpu_interrupt(cpu_single_env, CPU_INTERRUPT_HARD);
- }
- }
- break;
- default:
- break;
- }
-}
-
-static uint32_t openpic_cpu_read (void *opaque, uint32_t addr)
-{
- openpic_t *opp = opaque;
- IRQ_src_t *src;
- IRQ_dst_t *dst;
- uint32_t retval;
- int idx, n_IRQ;
-
- DPRINTF("%s: addr %08x\n", __func__, addr);
- retval = 0xFFFFFFFF;
- if (addr & 0xF)
- return retval;
- addr &= 0x1FFF0;
- idx = addr / 0x1000;
- dst = &opp->dst[idx];
- addr &= 0xFF0;
- switch (addr) {
- case 0x80: /* PCTP */
- retval = dst->pctp;
- break;
- case 0x90: /* WHOAMI */
- retval = idx;
- break;
- case 0xA0: /* PIAC */
- n_IRQ = IRQ_get_next(opp, &dst->raised);
- DPRINTF("PIAC: irq=%d\n", n_IRQ);
- if (n_IRQ == -1) {
- /* No more interrupt pending */
- retval = opp->spve;
- } else {
- src = &opp->src[n_IRQ];
- if (!test_bit(&src->ipvp, IPVP_ACTIVITY) ||
- !(IPVP_PRIORITY(src->ipvp) > dst->pctp)) {
- /* - Spurious level-sensitive IRQ
- * - Priorities has been changed
- * and the pending IRQ isn't allowed anymore
- */
- reset_bit(&src->ipvp, IPVP_ACTIVITY);
- retval = IPVP_VECTOR(opp->spve);
- } else {
- /* IRQ enter servicing state */
- IRQ_setbit(&dst->servicing, n_IRQ);
- retval = IPVP_VECTOR(src->ipvp);
- }
- IRQ_resetbit(&dst->raised, n_IRQ);
- dst->raised.next = -1;
- if (!test_bit(&src->ipvp, IPVP_SENSE)) {
- /* edge-sensitive IRQ */
- reset_bit(&src->ipvp, IPVP_ACTIVITY);
- src->pending = 0;
- }
- }
- break;
- case 0xB0: /* PEOI */
- retval = 0;
- break;
-#if MAX_IPI > 0
- case 0x40: /* IDE */
- case 0x50:
- idx = (addr - 0x40) >> 4;
- retval = read_IRQreg(opp, IRQ_IPI0 + idx, IRQ_IDE);
- break;
-#endif
- default:
- break;
- }
- DPRINTF("%s: => %08x\n", __func__, retval);
-#if defined OPENPIC_SWAP
- retval= bswap32(retval);
-#endif
-
- return retval;
-}
-
-static void openpic_buggy_write (void *opaque,
- target_phys_addr_t addr, uint32_t val)
-{
- printf("Invalid OPENPIC write access !\n");
-}
-
-static uint32_t openpic_buggy_read (void *opaque, target_phys_addr_t addr)
-{
- printf("Invalid OPENPIC read access !\n");
-
- return -1;
-}
-
-static void openpic_writel (void *opaque,
- target_phys_addr_t addr, uint32_t val)
-{
- openpic_t *opp = opaque;
-
- addr &= 0x3FFFF;
- DPRINTF("%s: offset %08x val: %08x\n", __func__, (int)addr, val);
- if (addr < 0x1100) {
- /* Global registers */
- openpic_gbl_write(opp, addr, val);
- } else if (addr < 0x10000) {
- /* Timers registers */
- openpic_timer_write(opp, addr, val);
- } else if (addr < 0x20000) {
- /* Source registers */
- openpic_src_write(opp, addr, val);
- } else {
- /* CPU registers */
- openpic_cpu_write(opp, addr, val);
- }
-}
-
-static uint32_t openpic_readl (void *opaque,target_phys_addr_t addr)
-{
- openpic_t *opp = opaque;
- uint32_t retval;
-
- addr &= 0x3FFFF;
- DPRINTF("%s: offset %08x\n", __func__, (int)addr);
- if (addr < 0x1100) {
- /* Global registers */
- retval = openpic_gbl_read(opp, addr);
- } else if (addr < 0x10000) {
- /* Timers registers */
- retval = openpic_timer_read(opp, addr);
- } else if (addr < 0x20000) {
- /* Source registers */
- retval = openpic_src_read(opp, addr);
- } else {
- /* CPU registers */
- retval = openpic_cpu_read(opp, addr);
- }
-
- return retval;
-}
-
-static CPUWriteMemoryFunc *openpic_write[] = {
- &openpic_buggy_write,
- &openpic_buggy_write,
- &openpic_writel,
-};
-
-static CPUReadMemoryFunc *openpic_read[] = {
- &openpic_buggy_read,
- &openpic_buggy_read,
- &openpic_readl,
-};
-
-static void openpic_map(PCIDevice *pci_dev, int region_num,
- uint32_t addr, uint32_t size, int type)
-{
- openpic_t *opp;
-
- DPRINTF("Map OpenPIC\n");
- opp = (openpic_t *)pci_dev;
- /* Global registers */
- DPRINTF("Register OPENPIC gbl %08x => %08x\n",
- addr + 0x1000, addr + 0x1000 + 0x100);
- /* Timer registers */
- DPRINTF("Register OPENPIC timer %08x => %08x\n",
- addr + 0x1100, addr + 0x1100 + 0x40 * MAX_TMR);
- /* Interrupt source registers */
- DPRINTF("Register OPENPIC src %08x => %08x\n",
- addr + 0x10000, addr + 0x10000 + 0x20 * (EXT_IRQ + 2));
- /* Per CPU registers */
- DPRINTF("Register OPENPIC dst %08x => %08x\n",
- addr + 0x20000, addr + 0x20000 + 0x1000 * MAX_CPU);
- cpu_register_physical_memory(addr, 0x40000, opp->mem_index);
-#if 0 // Don't implement ISU for now
- opp_io_memory = cpu_register_io_memory(0, openpic_src_read,
- openpic_src_write);
- cpu_register_physical_memory(isu_base, 0x20 * (EXT_IRQ + 2),
- opp_io_memory);
-#endif
-}
-
-openpic_t *openpic_init (PCIBus *bus, int *pmem_index, int nb_cpus)
-{
- openpic_t *opp;
- uint8_t *pci_conf;
- int i, m;
-
- /* XXX: for now, only one CPU is supported */
- if (nb_cpus != 1)
- return NULL;
- if (bus) {
- opp = (openpic_t *)pci_register_device(bus, "OpenPIC", sizeof(openpic_t),
- -1, NULL, NULL);
- if (opp == NULL)
- return NULL;
- pci_conf = opp->pci_dev.config;
- pci_conf[0x00] = 0x14; // IBM MPIC2
- pci_conf[0x01] = 0x10;
- pci_conf[0x02] = 0xFF;
- pci_conf[0x03] = 0xFF;
- pci_conf[0x0a] = 0x80; // PIC
- pci_conf[0x0b] = 0x08;
- pci_conf[0x0e] = 0x00; // header_type
- pci_conf[0x3d] = 0x00; // no interrupt pin
-
- /* Register I/O spaces */
- pci_register_io_region((PCIDevice *)opp, 0, 0x40000,
- PCI_ADDRESS_SPACE_MEM, &openpic_map);
- } else {
- opp = qemu_mallocz(sizeof(openpic_t));
- }
-
- opp->mem_index = cpu_register_io_memory(0, openpic_read,
- openpic_write, opp);
-
- // isu_base &= 0xFFFC0000;
- opp->nb_cpus = nb_cpus;
- /* Set IRQ types */
- for (i = 0; i < EXT_IRQ; i++) {
- opp->src[i].type = IRQ_EXTERNAL;
- }
- for (; i < IRQ_TIM0; i++) {
- opp->src[i].type = IRQ_SPECIAL;
- }
-#if MAX_IPI > 0
- m = IRQ_IPI0;
-#else
- m = IRQ_DBL0;
-#endif
- for (; i < m; i++) {
- opp->src[i].type = IRQ_TIMER;
- }
- for (; i < MAX_IRQ; i++) {
- opp->src[i].type = IRQ_INTERNAL;
- }
- openpic_reset(opp);
- if (pmem_index)
- *pmem_index = opp->mem_index;
- return opp;
-}
+++ /dev/null
-/*
- * QEMU PC System Emulator
- *
- * Copyright (c) 2003-2004 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "vl.h"
-
-/* output Bochs bios info messages */
-//#define DEBUG_BIOS
-
-#define BIOS_FILENAME "bios.bin"
-#define VGABIOS_FILENAME "vgabios.bin"
-#define VGABIOS_CIRRUS_FILENAME "vgabios-cirrus.bin"
-#define LINUX_BOOT_FILENAME "linux_boot.bin"
-
-#define KERNEL_LOAD_ADDR 0x00100000
-#define INITRD_LOAD_ADDR 0x00400000
-#define KERNEL_PARAMS_ADDR 0x00090000
-#define KERNEL_CMDLINE_ADDR 0x00099000
-
-int speaker_data_on;
-int dummy_refresh_clock;
-static fdctrl_t *floppy_controller;
-static RTCState *rtc_state;
-static USBPort *usb_root_ports[2];
-
-static void ioport80_write(void *opaque, uint32_t addr, uint32_t data)
-{
-}
-
-/* MSDOS compatibility mode FPU exception support */
-/* XXX: add IGNNE support */
-void cpu_set_ferr(CPUX86State *s)
-{
- pic_set_irq(13, 1);
-}
-
-static void ioportF0_write(void *opaque, uint32_t addr, uint32_t data)
-{
- pic_set_irq(13, 0);
-}
-
-/* TSC handling */
-
-uint64_t cpu_get_tsc(CPUX86State *env)
-{
- return qemu_get_clock(vm_clock);
-}
-
-/* PC cmos mappings */
-
-#define REG_EQUIPMENT_BYTE 0x14
-#define REG_IBM_CENTURY_BYTE 0x32
-#define REG_IBM_PS2_CENTURY_BYTE 0x37
-
-
-static inline int to_bcd(RTCState *s, int a)
-{
- return ((a / 10) << 4) | (a % 10);
-}
-
-static int cmos_get_fd_drive_type(int fd0)
-{
- int val;
-
- switch (fd0) {
- case 0:
- /* 1.44 Mb 3"5 drive */
- val = 4;
- break;
- case 1:
- /* 2.88 Mb 3"5 drive */
- val = 5;
- break;
- case 2:
- /* 1.2 Mb 5"5 drive */
- val = 2;
- break;
- default:
- val = 0;
- break;
- }
- return val;
-}
-
-static void cmos_init_hd(int type_ofs, int info_ofs, BlockDriverState *hd)
-{
- RTCState *s = rtc_state;
- int cylinders, heads, sectors;
- bdrv_get_geometry_hint(hd, &cylinders, &heads, §ors);
- rtc_set_memory(s, type_ofs, 47);
- rtc_set_memory(s, info_ofs, cylinders);
- rtc_set_memory(s, info_ofs + 1, cylinders >> 8);
- rtc_set_memory(s, info_ofs + 2, heads);
- rtc_set_memory(s, info_ofs + 3, 0xff);
- rtc_set_memory(s, info_ofs + 4, 0xff);
- rtc_set_memory(s, info_ofs + 5, 0xc0 | ((heads > 8) << 3));
- rtc_set_memory(s, info_ofs + 6, cylinders);
- rtc_set_memory(s, info_ofs + 7, cylinders >> 8);
- rtc_set_memory(s, info_ofs + 8, sectors);
-}
-
-/* hd_table must contain 4 block drivers */
-static void cmos_init(uint64_t ram_size, int boot_device, BlockDriverState **hd_table, time_t timeoffset)
-{
- RTCState *s = rtc_state;
- int val;
- int fd0, fd1, nb;
- time_t ti;
- struct tm *tm;
- int i;
-
- /* set the CMOS date */
- time(&ti);
- ti += timeoffset;
- if (rtc_utc)
- tm = gmtime(&ti);
- else
- tm = localtime(&ti);
- rtc_set_date(s, tm);
-
- val = to_bcd(s, (tm->tm_year / 100) + 19);
- rtc_set_memory(s, REG_IBM_CENTURY_BYTE, val);
- rtc_set_memory(s, REG_IBM_PS2_CENTURY_BYTE, val);
-
- /* various important CMOS locations needed by PC/Bochs bios */
-
- /* memory size */
- val = 640; /* base memory in K */
- rtc_set_memory(s, 0x15, val);
- rtc_set_memory(s, 0x16, val >> 8);
-
- val = (ram_size / 1024) - 1024;
- if (val > 65535)
- val = 65535;
- rtc_set_memory(s, 0x17, val);
- rtc_set_memory(s, 0x18, val >> 8);
- rtc_set_memory(s, 0x30, val);
- rtc_set_memory(s, 0x31, val >> 8);
-
- if (ram_size > (16 * 1024 * 1024))
- val = (ram_size / 65536) - ((16 * 1024 * 1024) / 65536);
- else
- val = 0;
- if (val > 65535)
- val = 65535;
- rtc_set_memory(s, 0x34, val);
- rtc_set_memory(s, 0x35, val >> 8);
-
- switch(boot_device) {
- case 'a':
- case 'b':
- //rtc_set_memory(s, 0x3d, 0x01); /* floppy boot */
- rtc_set_memory(s, 0x3d, 0x21); /* a->c->d */
- rtc_set_memory(s, 0x38, 0x30);
- break;
- default:
- case 'c':
- //rtc_set_memory(s, 0x3d, 0x02); /* hard drive boot */
- rtc_set_memory(s, 0x3d, 0x32); /* c->d->a */
- rtc_set_memory(s, 0x38, 0x10);
- break;
- case 'd':
- //rtc_set_memory(s, 0x3d, 0x03); /* CD-ROM boot */
- rtc_set_memory(s, 0x3d, 0x23); /* d->c->a */
- rtc_set_memory(s, 0x38, 0x10);
- break;
- }
-
- /* floppy type */
-
- fd0 = fdctrl_get_drive_type(floppy_controller, 0);
- fd1 = fdctrl_get_drive_type(floppy_controller, 1);
-
- val = (cmos_get_fd_drive_type(fd0) << 4) | cmos_get_fd_drive_type(fd1);
- rtc_set_memory(s, 0x10, val);
-
- val = 0;
- nb = 0;
- if (fd0 < 3)
- nb++;
- if (fd1 < 3)
- nb++;
- switch (nb) {
- case 0:
- break;
- case 1:
- val |= 0x01; /* 1 drive, ready for boot */
- break;
- case 2:
- val |= 0x41; /* 2 drives, ready for boot */
- break;
- }
- val |= 0x02; /* FPU is there */
- val |= 0x04; /* PS/2 mouse installed */
- rtc_set_memory(s, REG_EQUIPMENT_BYTE, val);
-
- /* hard drives */
-
- rtc_set_memory(s, 0x12, (hd_table[0] ? 0xf0 : 0) | (hd_table[1] ? 0x0f : 0));
- if (hd_table[0])
- cmos_init_hd(0x19, 0x1b, hd_table[0]);
- if (hd_table[1])
- cmos_init_hd(0x1a, 0x24, hd_table[1]);
-
- val = 0;
- for (i = 0; i < 4; i++) {
- if (hd_table[i]) {
- int cylinders, heads, sectors;
- uint8_t translation;
- /* NOTE: bdrv_get_geometry_hint() returns the geometry
- that the hard disk returns. It is always such that: 1 <=
- sects <= 63, 1 <= heads <= 16, 1 <= cylinders <=
- 16383. The BIOS geometry can be different. */
- bdrv_get_geometry_hint(hd_table[i], &cylinders, &heads, §ors);
- if (cylinders <= 1024 && heads <= 16 && sectors <= 63) {
- /* No translation. */
- translation = 0;
- } else {
- /* LBA translation. */
- translation = 1;
- }
- val |= translation << (i * 2);
- }
- }
- rtc_set_memory(s, 0x39, val);
-
- /* Disable check of 0x55AA signature on the last two bytes of
- first sector of disk. XXX: make it the default ? */
- // rtc_set_memory(s, 0x38, 1);
-}
-
-static void speaker_ioport_write(void *opaque, uint32_t addr, uint32_t val)
-{
- fprintf(stderr, "speaker port should not be handled in DM!\n");
-}
-
-static uint32_t speaker_ioport_read(void *opaque, uint32_t addr)
-{
- fprintf(stderr, "speaker port should not be handled in DM!\n");
- return 0;
-}
-
-static void ioport92_write(void *opaque, uint32_t addr, uint32_t val)
-{
- cpu_x86_set_a20(cpu_single_env, (val >> 1) & 1);
- /* XXX: bit 0 is fast reset */
-}
-
-static uint32_t ioport92_read(void *opaque, uint32_t addr)
-{
- return ((cpu_single_env->a20_mask >> 20) & 1) << 1;
-}
-
-/***********************************************************/
-/* Bochs BIOS debug ports */
-
-void bochs_bios_write(void *opaque, uint32_t addr, uint32_t val)
-{
- static const char shutdown_str[8] = "Shutdown";
- static int shutdown_index = 0;
-
- switch(addr) {
- /* Bochs BIOS messages */
- case 0x400:
- case 0x401:
- fprintf(stderr, "BIOS panic at rombios.c, line %d\n", val);
- exit(1);
- case 0x402:
- case 0x403:
-#ifdef DEBUG_BIOS
- fprintf(stderr, "%c", val);
-#endif
- break;
- case 0x8900:
- /* same as Bochs power off */
- if (val == shutdown_str[shutdown_index]) {
- shutdown_index++;
- if (shutdown_index == 8) {
- shutdown_index = 0;
- qemu_system_shutdown_request();
- }
- } else {
- shutdown_index = 0;
- }
- break;
-
- /* LGPL'ed VGA BIOS messages */
- case 0x501:
- case 0x502:
- fprintf(stderr, "VGA BIOS panic, line %d\n", val);
- exit(1);
- case 0x500:
- case 0x503:
-#ifdef DEBUG_BIOS
- fprintf(stderr, "%c", val);
-#endif
- break;
- }
-}
-
-void bochs_bios_init(void)
-{
- register_ioport_write(0x400, 1, 2, bochs_bios_write, NULL);
- register_ioport_write(0x401, 1, 2, bochs_bios_write, NULL);
- register_ioport_write(0x402, 1, 1, bochs_bios_write, NULL);
- register_ioport_write(0x403, 1, 1, bochs_bios_write, NULL);
- register_ioport_write(0x8900, 1, 1, bochs_bios_write, NULL);
-
- register_ioport_write(0x501, 1, 2, bochs_bios_write, NULL);
- register_ioport_write(0x502, 1, 2, bochs_bios_write, NULL);
- register_ioport_write(0x500, 1, 1, bochs_bios_write, NULL);
- register_ioport_write(0x503, 1, 1, bochs_bios_write, NULL);
-}
-
-
-int load_kernel(const char *filename, uint8_t *addr,
- uint8_t *real_addr)
-{
- int fd, size;
- int setup_sects;
-
- fd = open(filename, O_RDONLY | O_BINARY);
- if (fd < 0)
- return -1;
-
- /* load 16 bit code */
- if (read(fd, real_addr, 512) != 512)
- goto fail;
- setup_sects = real_addr[0x1F1];
- if (!setup_sects)
- setup_sects = 4;
- if (read(fd, real_addr + 512, setup_sects * 512) !=
- setup_sects * 512)
- goto fail;
-
- /* load 32 bit code */
- size = read(fd, addr, 16 * 1024 * 1024);
- if (size < 0)
- goto fail;
- close(fd);
- return size;
- fail:
- close(fd);
- return -1;
-}
-
-static const int ide_iobase[2] = { 0x1f0, 0x170 };
-static const int ide_iobase2[2] = { 0x3f6, 0x376 };
-static const int ide_irq[2] = { 14, 15 };
-
-#define NE2000_NB_MAX 6
-
-static int ne2000_io[NE2000_NB_MAX] = { 0x300, 0x320, 0x340, 0x360, 0x280, 0x380 };
-static int ne2000_irq[NE2000_NB_MAX] = { 9, 10, 11, 3, 4, 5 };
-
-static int serial_io[MAX_SERIAL_PORTS] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8 };
-static int serial_irq[MAX_SERIAL_PORTS] = { 4, 3, 4, 3 };
-
-//extern int acpi_init(unsigned int base);
-/* PIIX4 acpi pci configuration space, func 3 */
-extern void pci_piix4_acpi_init(PCIBus *bus);
-
-#define NOBIOS 1
-
-/* PC hardware initialisation */
-void pc_init(uint64_t ram_size, int vga_ram_size, int boot_device,
- DisplayState *ds, const char **fd_filename, int snapshot,
- const char *kernel_filename, const char *kernel_cmdline,
- const char *initrd_filename, time_t timeoffset)
-{
- SerialState *sp;
- char buf[1024];
- int ret, linux_boot, initrd_size, i, nb_nics1;
- PCIBus *pci_bus;
-
- linux_boot = (kernel_filename != NULL);
-
- /* allocate RAM */
-// cpu_register_physical_memory(0, ram_size, 0);
-
-#ifndef NOBIOS
- /* BIOS load */
- bios_offset = ram_size + vga_ram_size;
- vga_bios_offset = bios_offset + 256 * 1024;
-
- snprintf(buf, sizeof(buf), "%s/%s", bios_dir, BIOS_FILENAME);
- bios_size = get_image_size(buf);
- if (bios_size <= 0 ||
- (bios_size % 65536) != 0 ||
- bios_size > (256 * 1024)) {
- goto bios_error;
- }
- ret = load_image(buf, phys_ram_base + bios_offset);
- if (ret != bios_size) {
- bios_error:
- fprintf(stderr, "qemu: could not load PC bios '%s'\n", buf);
- exit(1);
- }
-
- /* VGA BIOS load */
- if (cirrus_vga_enabled) {
- snprintf(buf, sizeof(buf), "%s/%s", bios_dir, VGABIOS_CIRRUS_FILENAME);
- } else {
- snprintf(buf, sizeof(buf), "%s/%s", bios_dir, VGABIOS_FILENAME);
- }
- ret = load_image(buf, phys_ram_base + vga_bios_offset);
-#endif
-
-#ifndef NOBIOS
- /* setup basic memory access */
- cpu_register_physical_memory(0xc0000, 0x10000,
- vga_bios_offset | IO_MEM_ROM);
-
- /* map the last 128KB of the BIOS in ISA space */
- isa_bios_size = bios_size;
- if (isa_bios_size > (128 * 1024))
- isa_bios_size = 128 * 1024;
- cpu_register_physical_memory(0xd0000, (192 * 1024) - isa_bios_size,
- IO_MEM_UNASSIGNED);
- cpu_register_physical_memory(0x100000 - isa_bios_size,
- isa_bios_size,
- (bios_offset + bios_size - isa_bios_size) | IO_MEM_ROM);
- /* map all the bios at the top of memory */
- cpu_register_physical_memory((uint32_t)(-bios_size),
- bios_size, bios_offset | IO_MEM_ROM);
-#endif
-
- bochs_bios_init();
-
- if (linux_boot) {
- uint8_t bootsect[512];
- uint8_t old_bootsect[512];
-
- if (bs_table[0] == NULL) {
- fprintf(stderr, "A disk image must be given for 'hda' when booting a Linux kernel\n");
- exit(1);
- }
- snprintf(buf, sizeof(buf), "%s/%s", bios_dir, LINUX_BOOT_FILENAME);
- ret = load_image(buf, bootsect);
- if (ret != sizeof(bootsect)) {
- fprintf(stderr, "qemu: could not load linux boot sector '%s'\n",
- buf);
- exit(1);
- }
-
- if (bdrv_read(bs_table[0], 0, old_bootsect, 1) >= 0) {
- /* copy the MSDOS partition table */
- memcpy(bootsect + 0x1be, old_bootsect + 0x1be, 0x40);
- }
-
- bdrv_set_boot_sector(bs_table[0], bootsect, sizeof(bootsect));
-
- /* now we can load the kernel */
- ret = load_kernel(kernel_filename,
- phys_ram_base + KERNEL_LOAD_ADDR,
- phys_ram_base + KERNEL_PARAMS_ADDR);
- if (ret < 0) {
- fprintf(stderr, "qemu: could not load kernel '%s'\n",
- kernel_filename);
- exit(1);
- }
-
- /* load initrd */
- initrd_size = 0;
- if (initrd_filename) {
- initrd_size = load_image(initrd_filename, phys_ram_base + INITRD_LOAD_ADDR);
- if (initrd_size < 0) {
- fprintf(stderr, "qemu: could not load initial ram disk '%s'\n",
- initrd_filename);
- exit(1);
- }
- }
- if (initrd_size > 0) {
- stl_raw(phys_ram_base + KERNEL_PARAMS_ADDR + 0x218, INITRD_LOAD_ADDR);
- stl_raw(phys_ram_base + KERNEL_PARAMS_ADDR + 0x21c, initrd_size);
- }
- pstrcpy(phys_ram_base + KERNEL_CMDLINE_ADDR, 4096,
- kernel_cmdline);
- stw_raw(phys_ram_base + KERNEL_PARAMS_ADDR + 0x20, 0xA33F);
- stw_raw(phys_ram_base + KERNEL_PARAMS_ADDR + 0x22,
- KERNEL_CMDLINE_ADDR - KERNEL_PARAMS_ADDR);
- /* loader type */
- stw_raw(phys_ram_base + KERNEL_PARAMS_ADDR + 0x210, 0x01);
- }
-
- if (pci_enabled) {
- pci_bus = i440fx_init();
- piix3_init(pci_bus);
- } else {
- pci_bus = NULL;
- }
-
- /* init basic PC hardware */
- register_ioport_write(0x80, 1, 1, ioport80_write, NULL);
-
- register_ioport_write(0xf0, 1, 1, ioportF0_write, NULL);
-
- if (cirrus_vga_enabled) {
- if (pci_enabled) {
- pci_cirrus_vga_init(pci_bus,
- ds, NULL, ram_size,
- vga_ram_size);
- } else {
- isa_cirrus_vga_init(ds, NULL, ram_size,
- vga_ram_size);
- }
- } else {
- vga_initialize(pci_bus, ds, NULL, ram_size,
- vga_ram_size);
- }
-
- rtc_state = rtc_init(0x70, 8);
- register_ioport_read(0x61, 1, 1, speaker_ioport_read, NULL);
- register_ioport_write(0x61, 1, 1, speaker_ioport_write, NULL);
-
- register_ioport_read(0x92, 1, 1, ioport92_read, NULL);
- register_ioport_write(0x92, 1, 1, ioport92_write, NULL);
-
- pic_init();
-
- for(i = 0; i < MAX_SERIAL_PORTS; i++) {
- if (serial_hds[i]) {
- sp = serial_init(serial_io[i], serial_irq[i], serial_hds[i]);
- if (i == serial_summa_port) {
- summa_init(sp, serial_hds[i]);
- fprintf(stderr, "Serial port %d (COM%d) initialized for Summagraphics\n",
- i, i+1);
- }
- }
- }
-
- if (pci_enabled) {
- for(i = 0; i < nb_nics; i++) {
- if (nic_ne2000)
- pci_ne2000_init(pci_bus, &nd_table[i]);
- else
- pci_pcnet_init(pci_bus, &nd_table[i]);
- }
- pci_piix3_ide_init(pci_bus, bs_table);
- } else {
- nb_nics1 = nb_nics;
- if (nb_nics1 > NE2000_NB_MAX)
- nb_nics1 = NE2000_NB_MAX;
- for(i = 0; i < nb_nics1; i++) {
- isa_ne2000_init(ne2000_io[i], ne2000_irq[i], &nd_table[i]);
- }
-
- for(i = 0; i < 2; i++) {
- isa_ide_init(ide_iobase[i], ide_iobase2[i], ide_irq[i],
- bs_table[2 * i], bs_table[2 * i + 1]);
- }
- }
-
- kbd_init();
- DMA_init(0);
-
- if (audio_enabled) {
- AUD_init();
-#ifdef USE_SB16
- if (sb16_enabled)
- SB16_init();
-#endif
- }
-
-
- floppy_controller = fdctrl_init(6, 2, 0, 0x3f0, fd_table);
-
- cmos_init(ram_size, boot_device, bs_table, timeoffset);
-// using PIIX4 acpi model
-// acpi_init(0x8000);
- pci_piix4_acpi_init(pci_bus);
-
- if (pci_enabled && usb_enabled) {
- usb_uhci_init(pci_bus, usb_root_ports);
- usb_attach(usb_root_ports[0], vm_usb_hub);
- }
-
- /* must be done after all PCI devices are instanciated */
- /* XXX: should be done in the Bochs BIOS */
- if (pci_enabled) {
- pci_bios_init();
- }
- port_e9_init();
-}
+++ /dev/null
-/*
- * QEMU PCI bus manager
- *
- * Copyright (c) 2004 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "vl.h"
-
-//#define DEBUG_PCI
-
-#define PCI_VENDOR_ID 0x00 /* 16 bits */
-#define PCI_DEVICE_ID 0x02 /* 16 bits */
-#define PCI_COMMAND 0x04 /* 16 bits */
-#define PCI_COMMAND_IO 0x1 /* Enable response in I/O space */
-#define PCI_COMMAND_MEMORY 0x2 /* Enable response in Memory space */
-#define PCI_CLASS_DEVICE 0x0a /* Device class */
-#define PCI_INTERRUPT_LINE 0x3c /* 8 bits */
-#define PCI_INTERRUPT_PIN 0x3d /* 8 bits */
-#define PCI_MIN_GNT 0x3e /* 8 bits */
-#define PCI_MAX_LAT 0x3f /* 8 bits */
-
-/* just used for simpler irq handling. */
-#define PCI_DEVICES_MAX 64
-#define PCI_IRQ_WORDS ((PCI_DEVICES_MAX + 31) / 32)
-
-struct PCIBus {
- int bus_num;
- int devfn_min;
- void (*set_irq)(PCIDevice *pci_dev, int irq_num, int level);
- uint32_t config_reg; /* XXX: suppress */
- openpic_t *openpic; /* XXX: suppress */
- PCIDevice *devices[256];
-};
-
-target_phys_addr_t pci_mem_base;
-static int pci_irq_index;
-static uint32_t pci_irq_levels[4][PCI_IRQ_WORDS];
-static PCIBus *first_bus;
-extern FILE *logfile;
-
-static PCIBus *pci_register_bus(void)
-{
- PCIBus *bus;
- bus = qemu_mallocz(sizeof(PCIBus));
- first_bus = bus;
- return bus;
-}
-
-void generic_pci_save(QEMUFile* f, void *opaque)
-{
- PCIDevice* s=(PCIDevice*)opaque;
-
- qemu_put_buffer(f, s->config, 256);
-}
-
-int generic_pci_load(QEMUFile* f, void *opaque, int version_id)
-{
- PCIDevice* s=(PCIDevice*)opaque;
-
- if (version_id != 1)
- return -EINVAL;
-
- qemu_get_buffer(f, s->config, 256);
- return 0;
-}
-
-/* -1 for devfn means auto assign */
-PCIDevice *pci_register_device(PCIBus *bus, const char *name,
- int instance_size, int devfn,
- PCIConfigReadFunc *config_read,
- PCIConfigWriteFunc *config_write)
-{
- PCIDevice *pci_dev;
-
- if (pci_irq_index >= PCI_DEVICES_MAX)
- return NULL;
-
- if (devfn < 0) {
- for(devfn = bus->devfn_min ; devfn < 256; devfn += 8) {
- if (!bus->devices[devfn])
- goto found;
- }
- return NULL;
- found: ;
- }
- pci_dev = qemu_mallocz(instance_size);
- if (!pci_dev)
- return NULL;
- pci_dev->bus = bus;
- pci_dev->devfn = devfn;
- pstrcpy(pci_dev->name, sizeof(pci_dev->name), name);
-
- if (!config_read)
- config_read = pci_default_read_config;
- if (!config_write)
- config_write = pci_default_write_config;
- pci_dev->config_read = config_read;
- pci_dev->config_write = config_write;
- pci_dev->irq_index = pci_irq_index++;
- bus->devices[devfn] = pci_dev;
- return pci_dev;
-}
-
-void pci_register_io_region(PCIDevice *pci_dev, int region_num,
- uint32_t size, int type,
- PCIMapIORegionFunc *map_func)
-{
- PCIIORegion *r;
-
- if ((unsigned int)region_num >= PCI_NUM_REGIONS)
- return;
- r = &pci_dev->io_regions[region_num];
- r->addr = -1;
- r->size = size;
- r->type = type;
- r->map_func = map_func;
-}
-
-static void pci_addr_writel(void* opaque, uint32_t addr, uint32_t val)
-{
- PCIBus *s = opaque;
- s->config_reg = val;
-}
-
-static uint32_t pci_addr_readl(void* opaque, uint32_t addr)
-{
- PCIBus *s = opaque;
- return s->config_reg;
-}
-
-static void pci_update_mappings(PCIDevice *d)
-{
- PCIIORegion *r;
- int cmd, i;
- uint32_t last_addr, new_addr, config_ofs;
-
- cmd = le16_to_cpu(*(uint16_t *)(d->config + PCI_COMMAND));
- for(i = 0; i < PCI_NUM_REGIONS; i++) {
- r = &d->io_regions[i];
- if (i == PCI_ROM_SLOT) {
- config_ofs = 0x30;
- } else {
- config_ofs = 0x10 + i * 4;
- }
- if (r->size != 0) {
- if (r->type & PCI_ADDRESS_SPACE_IO) {
- if (cmd & PCI_COMMAND_IO) {
- new_addr = le32_to_cpu(*(uint32_t *)(d->config +
- config_ofs));
- new_addr = new_addr & ~(r->size - 1);
- last_addr = new_addr + r->size - 1;
- /* NOTE: we have only 64K ioports on PC */
- if (last_addr <= new_addr || new_addr == 0 ||
- last_addr >= 0x10000) {
- new_addr = -1;
- }
- } else {
- new_addr = -1;
- }
- } else {
- if (cmd & PCI_COMMAND_MEMORY) {
- new_addr = le32_to_cpu(*(uint32_t *)(d->config +
- config_ofs));
- /* the ROM slot has a specific enable bit */
- if (i == PCI_ROM_SLOT && !(new_addr & 1))
- goto no_mem_map;
- new_addr = new_addr & ~(r->size - 1);
- last_addr = new_addr + r->size - 1;
- /* NOTE: we do not support wrapping */
- /* XXX: as we cannot support really dynamic
- mappings, we handle specific values as invalid
- mappings. */
- if (last_addr <= new_addr || new_addr == 0 ||
- last_addr == -1) {
- new_addr = -1;
- }
- } else {
- no_mem_map:
- new_addr = -1;
- }
- }
- /* now do the real mapping */
- if (new_addr != r->addr) {
- if (r->addr != -1) {
- if (r->type & PCI_ADDRESS_SPACE_IO) {
- int class;
- /* NOTE: specific hack for IDE in PC case:
- only one byte must be mapped. */
- class = d->config[0x0a] | (d->config[0x0b] << 8);
- if (class == 0x0101 && r->size == 4) {
- isa_unassign_ioport(r->addr + 2, 1);
- } else {
- isa_unassign_ioport(r->addr, r->size);
- }
- } else {
- cpu_register_physical_memory(r->addr + pci_mem_base,
- r->size,
- IO_MEM_UNASSIGNED);
- }
- }
- r->addr = new_addr;
- if (r->addr != -1) {
- r->map_func(d, i, r->addr, r->size, r->type);
- }
- }
- }
- }
-}
-
-uint32_t pci_default_read_config(PCIDevice *d,
- uint32_t address, int len)
-{
- uint32_t val;
- switch(len) {
- case 1:
- val = d->config[address];
- break;
- case 2:
- val = le16_to_cpu(*(uint16_t *)(d->config + address));
- break;
- default:
- case 4:
- val = le32_to_cpu(*(uint32_t *)(d->config + address));
- break;
- }
- return val;
-}
-
-void pci_default_write_config(PCIDevice *d,
- uint32_t address, uint32_t val, int len)
-{
- int can_write, i;
- uint32_t end, addr;
-
- if (len == 4 && ((address >= 0x10 && address < 0x10 + 4 * 6) ||
- (address >= 0x30 && address < 0x34))) {
- PCIIORegion *r;
- int reg;
-
- if ( address >= 0x30 ) {
- reg = PCI_ROM_SLOT;
- }else{
- reg = (address - 0x10) >> 2;
- }
- r = &d->io_regions[reg];
- if (r->size == 0)
- goto default_config;
- /* compute the stored value */
- if (reg == PCI_ROM_SLOT) {
- /* keep ROM enable bit */
- val &= (~(r->size - 1)) | 1;
- } else {
- val &= ~(r->size - 1);
- val |= r->type;
- }
- *(uint32_t *)(d->config + address) = cpu_to_le32(val);
- pci_update_mappings(d);
- return;
- }
- default_config:
- /* not efficient, but simple */
- addr = address;
- for(i = 0; i < len; i++) {
- /* default read/write accesses */
- switch(d->config[0x0e]) {
- case 0x00:
- case 0x80:
- switch(addr) {
- case 0x00:
- case 0x01:
- case 0x02:
- case 0x03:
- case 0x08:
- case 0x09:
- case 0x0a:
- case 0x0b:
- case 0x0e:
- case 0x10 ... 0x27: /* base */
- case 0x30 ... 0x33: /* rom */
- case 0x3d:
- can_write = 0;
- break;
- default:
- can_write = 1;
- break;
- }
- break;
- default:
- case 0x01:
- switch(addr) {
- case 0x00:
- case 0x01:
- case 0x02:
- case 0x03:
- case 0x08:
- case 0x09:
- case 0x0a:
- case 0x0b:
- case 0x0e:
- case 0x38 ... 0x3b: /* rom */
- case 0x3d:
- can_write = 0;
- break;
- default:
- can_write = 1;
- break;
- }
- break;
- }
- if (can_write) {
- d->config[addr] = val;
- }
- addr++;
- val >>= 8;
- }
-
- end = address + len;
- if (end > PCI_COMMAND && address < (PCI_COMMAND + 2)) {
- /* if the command register is modified, we must modify the mappings */
- pci_update_mappings(d);
- }
-}
-
-static void pci_data_write(void *opaque, uint32_t addr,
- uint32_t val, int len)
-{
- PCIBus *s = opaque;
- PCIDevice *pci_dev;
- int config_addr, bus_num;
-
-#if defined(DEBUG_PCI) && 0
- printf("pci_data_write: addr=%08x val=%08x len=%d\n",
- s->config_reg, val, len);
-#endif
- if (!(s->config_reg & (1 << 31))) {
- return;
- }
- if ((s->config_reg & 0x3) != 0) {
- return;
- }
- bus_num = (s->config_reg >> 16) & 0xff;
- if (bus_num != 0)
- return;
- pci_dev = s->devices[(s->config_reg >> 8) & 0xff];
- if (!pci_dev)
- return;
- config_addr = (s->config_reg & 0xfc) | (addr & 3);
-#if defined(DEBUG_PCI)
- printf("pci_config_write: %s: addr=%02x val=%08x len=%d\n",
- pci_dev->name, config_addr, val, len);
-#endif
- pci_dev->config_write(pci_dev, config_addr, val, len);
-}
-
-static uint32_t pci_data_read(void *opaque, uint32_t addr,
- int len)
-{
- PCIBus *s = opaque;
- PCIDevice *pci_dev;
- int config_addr, bus_num;
- uint32_t val;
-
- if (!(s->config_reg & (1 << 31)))
- goto fail;
- if ((s->config_reg & 0x3) != 0)
- goto fail;
- bus_num = (s->config_reg >> 16) & 0xff;
- if (bus_num != 0)
- goto fail;
- pci_dev = s->devices[(s->config_reg >> 8) & 0xff];
- if (!pci_dev) {
- fail:
- switch(len) {
- case 1:
- val = 0xff;
- break;
- case 2:
- val = 0xffff;
- break;
- default:
- case 4:
- val = 0xffffffff;
- break;
- }
- goto the_end;
- }
- config_addr = (s->config_reg & 0xfc) | (addr & 3);
- val = pci_dev->config_read(pci_dev, config_addr, len);
-#if defined(DEBUG_PCI)
- printf("pci_config_read: %s: addr=%02x val=%08x len=%d\n",
- pci_dev->name, config_addr, val, len);
-#endif
- the_end:
-#if defined(DEBUG_PCI) && 0
- printf("pci_data_read: addr=%08x val=%08x len=%d\n",
- s->config_reg, val, len);
-#endif
- return val;
-}
-
-static void pci_data_writeb(void* opaque, uint32_t addr, uint32_t val)
-{
- pci_data_write(opaque, addr, val, 1);
-}
-
-static void pci_data_writew(void* opaque, uint32_t addr, uint32_t val)
-{
- pci_data_write(opaque, addr, val, 2);
-}
-
-static void pci_data_writel(void* opaque, uint32_t addr, uint32_t val)
-{
- pci_data_write(opaque, addr, val, 4);
-}
-
-static uint32_t pci_data_readb(void* opaque, uint32_t addr)
-{
- return pci_data_read(opaque, addr, 1);
-}
-
-static uint32_t pci_data_readw(void* opaque, uint32_t addr)
-{
- return pci_data_read(opaque, addr, 2);
-}
-
-static uint32_t pci_data_readl(void* opaque, uint32_t addr)
-{
- return pci_data_read(opaque, addr, 4);
-}
-
-/* i440FX PCI bridge */
-
-static void piix3_set_irq(PCIDevice *pci_dev, int irq_num, int level);
-
-PCIBus *i440fx_init(void)
-{
- PCIBus *s;
- PCIDevice *d;
-
- s = pci_register_bus();
- s->set_irq = piix3_set_irq;
-
- register_ioport_write(0xcf8, 4, 4, pci_addr_writel, s);
- register_ioport_read(0xcf8, 4, 4, pci_addr_readl, s);
-
- register_ioport_write(0xcfc, 4, 1, pci_data_writeb, s);
- register_ioport_write(0xcfc, 4, 2, pci_data_writew, s);
- register_ioport_write(0xcfc, 4, 4, pci_data_writel, s);
- register_ioport_read(0xcfc, 4, 1, pci_data_readb, s);
- register_ioport_read(0xcfc, 4, 2, pci_data_readw, s);
- register_ioport_read(0xcfc, 4, 4, pci_data_readl, s);
-
- d = pci_register_device(s, "i440FX", sizeof(PCIDevice), 0,
- NULL, NULL);
-
- d->config[0x00] = 0x86; // vendor_id
- d->config[0x01] = 0x80;
- d->config[0x02] = 0x37; // device_id
- d->config[0x03] = 0x12;
- d->config[0x08] = 0x02; // revision
- d->config[0x0a] = 0x00; // class_sub = host2pci
- d->config[0x0b] = 0x06; // class_base = PCI_bridge
- d->config[0x0e] = 0x00; // header_type
- return s;
-}
-
-/* PIIX3 PCI to ISA bridge */
-
-typedef struct PIIX3State {
- PCIDevice dev;
-} PIIX3State;
-
-PIIX3State *piix3_state;
-
-/* return the global irq number corresponding to a given device irq
- pin. We could also use the bus number to have a more precise
- mapping. */
-static inline int pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num)
-{
- int slot_addend;
- slot_addend = (pci_dev->devfn >> 3);
- return (irq_num + slot_addend) & 3;
-}
-
-static void piix3_set_irq(PCIDevice *pci_dev, int irq_num, int level)
-{
- int irq_index, shift, pic_irq, pic_level;
- uint32_t *p;
-
- irq_num = pci_slot_get_pirq(pci_dev, irq_num);
- irq_index = pci_dev->irq_index;
- p = &pci_irq_levels[irq_num][irq_index >> 5];
- shift = (irq_index & 0x1f);
- *p = (*p & ~(1 << shift)) | (level << shift);
-
- /* now we change the pic irq level according to the piix irq mappings */
- pic_irq = piix3_state->dev.config[0x60 + irq_num];
- if (pic_irq < 16) {
- /* the pic level is the logical OR of all the PCI irqs mapped
- to it */
- pic_level = 0;
-#if (PCI_IRQ_WORDS == 2)
- pic_level = ((pci_irq_levels[irq_num][0] |
- pci_irq_levels[irq_num][1]) != 0);
-#else
- {
- int i;
- pic_level = 0;
- for(i = 0; i < PCI_IRQ_WORDS; i++) {
- if (pci_irq_levels[irq_num][i]) {
- pic_level = 1;
- break;
- }
- }
- }
-#endif
- pic_set_irq(pic_irq, pic_level);
- }
-}
-
-static void piix3_reset(PIIX3State *d)
-{
- uint8_t *pci_conf = d->dev.config;
-
- pci_conf[0x04] = 0x07; // master, memory and I/O
- pci_conf[0x05] = 0x00;
- pci_conf[0x06] = 0x00;
- pci_conf[0x07] = 0x02; // PCI_status_devsel_medium
- pci_conf[0x4c] = 0x4d;
- pci_conf[0x4e] = 0x03;
- pci_conf[0x4f] = 0x00;
- pci_conf[0x60] = 0x80;
- pci_conf[0x69] = 0x02;
- pci_conf[0x70] = 0x80;
- pci_conf[0x76] = 0x0c;
- pci_conf[0x77] = 0x0c;
- pci_conf[0x78] = 0x02;
- pci_conf[0x79] = 0x00;
- pci_conf[0x80] = 0x00;
- pci_conf[0x82] = 0x00;
- pci_conf[0xa0] = 0x08;
- pci_conf[0xa0] = 0x08;
- pci_conf[0xa2] = 0x00;
- pci_conf[0xa3] = 0x00;
- pci_conf[0xa4] = 0x00;
- pci_conf[0xa5] = 0x00;
- pci_conf[0xa6] = 0x00;
- pci_conf[0xa7] = 0x00;
- pci_conf[0xa8] = 0x0f;
- pci_conf[0xaa] = 0x00;
- pci_conf[0xab] = 0x00;
- pci_conf[0xac] = 0x00;
- pci_conf[0xae] = 0x00;
-}
-
-#define PIIX_CONFIG_XBCS 0x4f
-void piix3_write_config(PCIDevice *d,
- uint32_t address, uint32_t val, int len)
-{
- if ((PIIX3State *)d != piix3_state){
- fprintf(logfile, "piix3_write_config: error PCIDevice\n");
- return;
- }
-
- pci_default_write_config(d, address, val, len);
-}
-
-
-void piix3_init(PCIBus *bus)
-{
- PIIX3State *d;
- uint8_t *pci_conf;
-
- d = (PIIX3State *)pci_register_device(bus, "PIIX3", sizeof(PIIX3State),
- -1, NULL, piix3_write_config);
- register_savevm("PIIX3", 0, 1, generic_pci_save, generic_pci_load, d);
-
- piix3_state = d;
- pci_conf = d->dev.config;
-
- pci_conf[0x00] = 0x86; // Intel
- pci_conf[0x01] = 0x80;
- pci_conf[0x02] = 0x00; // 82371SB PIIX3 PCI-to-ISA bridge (Step A1)
- pci_conf[0x03] = 0x70;
- pci_conf[0x0a] = 0x01; // class_sub = PCI_ISA
- pci_conf[0x0b] = 0x06; // class_base = PCI_bridge
- pci_conf[0x0e] = 0x80; // header_type = PCI_multifunction, generic
-
- piix3_reset(d);
-}
-
-/* PREP pci init */
-
-static inline void set_config(PCIBus *s, target_phys_addr_t addr)
-{
- int devfn, i;
-
- for(i = 0; i < 11; i++) {
- if ((addr & (1 << (11 + i))) != 0)
- break;
- }
- devfn = ((addr >> 8) & 7) | (i << 3);
- s->config_reg = 0x80000000 | (addr & 0xfc) | (devfn << 8);
-}
-
-static void PPC_PCIIO_writeb (void *opaque, target_phys_addr_t addr, uint32_t val)
-{
- PCIBus *s = opaque;
- set_config(s, addr);
- pci_data_write(s, addr, val, 1);
-}
-
-static void PPC_PCIIO_writew (void *opaque, target_phys_addr_t addr, uint32_t val)
-{
- PCIBus *s = opaque;
- set_config(s, addr);
-#ifdef TARGET_WORDS_BIGENDIAN
- val = bswap16(val);
-#endif
- pci_data_write(s, addr, val, 2);
-}
-
-static void PPC_PCIIO_writel (void *opaque, target_phys_addr_t addr, uint32_t val)
-{
- PCIBus *s = opaque;
- set_config(s, addr);
-#ifdef TARGET_WORDS_BIGENDIAN
- val = bswap32(val);
-#endif
- pci_data_write(s, addr, val, 4);
-}
-
-static uint32_t PPC_PCIIO_readb (void *opaque, target_phys_addr_t addr)
-{
- PCIBus *s = opaque;
- uint32_t val;
- set_config(s, addr);
- val = pci_data_read(s, addr, 1);
- return val;
-}
-
-static uint32_t PPC_PCIIO_readw (void *opaque, target_phys_addr_t addr)
-{
- PCIBus *s = opaque;
- uint32_t val;
- set_config(s, addr);
- val = pci_data_read(s, addr, 2);
-#ifdef TARGET_WORDS_BIGENDIAN
- val = bswap16(val);
-#endif
- return val;
-}
-
-static uint32_t PPC_PCIIO_readl (void *opaque, target_phys_addr_t addr)
-{
- PCIBus *s = opaque;
- uint32_t val;
- set_config(s, addr);
- val = pci_data_read(s, addr, 4);
-#ifdef TARGET_WORDS_BIGENDIAN
- val = bswap32(val);
-#endif
- return val;
-}
-
-static CPUWriteMemoryFunc *PPC_PCIIO_write[] = {
- &PPC_PCIIO_writeb,
- &PPC_PCIIO_writew,
- &PPC_PCIIO_writel,
-};
-
-static CPUReadMemoryFunc *PPC_PCIIO_read[] = {
- &PPC_PCIIO_readb,
- &PPC_PCIIO_readw,
- &PPC_PCIIO_readl,
-};
-
-static void prep_set_irq(PCIDevice *d, int irq_num, int level)
-{
- /* XXX: we do not simulate the hardware - we rely on the BIOS to
- set correctly for irq line field */
- pic_set_irq(d->config[PCI_INTERRUPT_LINE], level);
-}
-
-PCIBus *pci_prep_init(void)
-{
- PCIBus *s;
- PCIDevice *d;
- int PPC_io_memory;
-
- s = pci_register_bus();
- s->set_irq = prep_set_irq;
-
- PPC_io_memory = cpu_register_io_memory(0, PPC_PCIIO_read,
- PPC_PCIIO_write, s);
- cpu_register_physical_memory(0x80800000, 0x00400000, PPC_io_memory);
-
- d = pci_register_device(s, "PREP PCI Bridge", sizeof(PCIDevice), 0,
- NULL, NULL);
-
- /* XXX: put correct IDs */
- d->config[0x00] = 0x11; // vendor_id
- d->config[0x01] = 0x10;
- d->config[0x02] = 0x26; // device_id
- d->config[0x03] = 0x00;
- d->config[0x08] = 0x02; // revision
- d->config[0x0a] = 0x04; // class_sub = pci2pci
- d->config[0x0b] = 0x06; // class_base = PCI_bridge
- d->config[0x0e] = 0x01; // header_type
- return s;
-}
-
-
-/* pmac pci init */
-
-#if 0
-/* Grackle PCI host */
-static void pci_grackle_config_writel (void *opaque, target_phys_addr_t addr,
- uint32_t val)
-{
- PCIBus *s = opaque;
-#ifdef TARGET_WORDS_BIGENDIAN
- val = bswap32(val);
-#endif
- s->config_reg = val;
-}
-
-static uint32_t pci_grackle_config_readl (void *opaque, target_phys_addr_t addr)
-{
- PCIBus *s = opaque;
- uint32_t val;
-
- val = s->config_reg;
-#ifdef TARGET_WORDS_BIGENDIAN
- val = bswap32(val);
-#endif
- return val;
-}
-
-static CPUWriteMemoryFunc *pci_grackle_config_write[] = {
- &pci_grackle_config_writel,
- &pci_grackle_config_writel,
- &pci_grackle_config_writel,
-};
-
-static CPUReadMemoryFunc *pci_grackle_config_read[] = {
- &pci_grackle_config_readl,
- &pci_grackle_config_readl,
- &pci_grackle_config_readl,
-};
-
-static void pci_grackle_writeb (void *opaque, target_phys_addr_t addr,
- uint32_t val)
-{
- PCIBus *s = opaque;
- pci_data_write(s, addr, val, 1);
-}
-
-static void pci_grackle_writew (void *opaque, target_phys_addr_t addr,
- uint32_t val)
-{
- PCIBus *s = opaque;
-#ifdef TARGET_WORDS_BIGENDIAN
- val = bswap16(val);
-#endif
- pci_data_write(s, addr, val, 2);
-}
-
-static void pci_grackle_writel (void *opaque, target_phys_addr_t addr,
- uint32_t val)
-{
- PCIBus *s = opaque;
-#ifdef TARGET_WORDS_BIGENDIAN
- val = bswap32(val);
-#endif
- pci_data_write(s, addr, val, 4);
-}
-
-static uint32_t pci_grackle_readb (void *opaque, target_phys_addr_t addr)
-{
- PCIBus *s = opaque;
- uint32_t val;
- val = pci_data_read(s, addr, 1);
- return val;
-}
-
-static uint32_t pci_grackle_readw (void *opaque, target_phys_addr_t addr)
-{
- PCIBus *s = opaque;
- uint32_t val;
- val = pci_data_read(s, addr, 2);
-#ifdef TARGET_WORDS_BIGENDIAN
- val = bswap16(val);
-#endif
- return val;
-}
-
-static uint32_t pci_grackle_readl (void *opaque, target_phys_addr_t addr)
-{
- PCIBus *s = opaque;
- uint32_t val;
-
- val = pci_data_read(s, addr, 4);
-#ifdef TARGET_WORDS_BIGENDIAN
- val = bswap32(val);
-#endif
- return val;
-}
-
-static CPUWriteMemoryFunc *pci_grackle_write[] = {
- &pci_grackle_writeb,
- &pci_grackle_writew,
- &pci_grackle_writel,
-};
-
-static CPUReadMemoryFunc *pci_grackle_read[] = {
- &pci_grackle_readb,
- &pci_grackle_readw,
- &pci_grackle_readl,
-};
-#endif
-
-/* Uninorth PCI host (for all Mac99 and newer machines */
-static void pci_unin_main_config_writel (void *opaque, target_phys_addr_t addr,
- uint32_t val)
-{
- PCIBus *s = opaque;
- int i;
-
-#ifdef TARGET_WORDS_BIGENDIAN
- val = bswap32(val);
-#endif
-
- for (i = 11; i < 32; i++) {
- if ((val & (1 << i)) != 0)
- break;
- }
-#if 0
- s->config_reg = 0x80000000 | (1 << 16) | (val & 0x7FC) | (i << 11);
-#else
- s->config_reg = 0x80000000 | (0 << 16) | (val & 0x7FC) | (i << 11);
-#endif
-}
-
-static uint32_t pci_unin_main_config_readl (void *opaque,
- target_phys_addr_t addr)
-{
- PCIBus *s = opaque;
- uint32_t val;
- int devfn;
-
- devfn = (s->config_reg >> 8) & 0xFF;
- val = (1 << (devfn >> 3)) | ((devfn & 0x07) << 8) | (s->config_reg & 0xFC);
-#ifdef TARGET_WORDS_BIGENDIAN
- val = bswap32(val);
-#endif
-
- return val;
-}
-
-static CPUWriteMemoryFunc *pci_unin_main_config_write[] = {
- &pci_unin_main_config_writel,
- &pci_unin_main_config_writel,
- &pci_unin_main_config_writel,
-};
-
-static CPUReadMemoryFunc *pci_unin_main_config_read[] = {
- &pci_unin_main_config_readl,
- &pci_unin_main_config_readl,
- &pci_unin_main_config_readl,
-};
-
-static void pci_unin_main_writeb (void *opaque, target_phys_addr_t addr,
- uint32_t val)
-{
- PCIBus *s = opaque;
- pci_data_write(s, addr & 7, val, 1);
-}
-
-static void pci_unin_main_writew (void *opaque, target_phys_addr_t addr,
- uint32_t val)
-{
- PCIBus *s = opaque;
-#ifdef TARGET_WORDS_BIGENDIAN
- val = bswap16(val);
-#endif
- pci_data_write(s, addr & 7, val, 2);
-}
-
-static void pci_unin_main_writel (void *opaque, target_phys_addr_t addr,
- uint32_t val)
-{
- PCIBus *s = opaque;
-#ifdef TARGET_WORDS_BIGENDIAN
- val = bswap32(val);
-#endif
- pci_data_write(s, addr & 7, val, 4);
-}
-
-static uint32_t pci_unin_main_readb (void *opaque, target_phys_addr_t addr)
-{
- PCIBus *s = opaque;
- uint32_t val;
-
- val = pci_data_read(s, addr & 7, 1);
-
- return val;
-}
-
-static uint32_t pci_unin_main_readw (void *opaque, target_phys_addr_t addr)
-{
- PCIBus *s = opaque;
- uint32_t val;
-
- val = pci_data_read(s, addr & 7, 2);
-#ifdef TARGET_WORDS_BIGENDIAN
- val = bswap16(val);
-#endif
-
- return val;
-}
-
-static uint32_t pci_unin_main_readl (void *opaque, target_phys_addr_t addr)
-{
- PCIBus *s = opaque;
- uint32_t val;
-
- val = pci_data_read(s, addr, 4);
-#ifdef TARGET_WORDS_BIGENDIAN
- val = bswap32(val);
-#endif
-
- return val;
-}
-
-static CPUWriteMemoryFunc *pci_unin_main_write[] = {
- &pci_unin_main_writeb,
- &pci_unin_main_writew,
- &pci_unin_main_writel,
-};
-
-static CPUReadMemoryFunc *pci_unin_main_read[] = {
- &pci_unin_main_readb,
- &pci_unin_main_readw,
- &pci_unin_main_readl,
-};
-
-#if 0
-
-static void pci_unin_config_writel (void *opaque, target_phys_addr_t addr,
- uint32_t val)
-{
- PCIBus *s = opaque;
-
-#ifdef TARGET_WORDS_BIGENDIAN
- val = bswap32(val);
-#endif
- s->config_reg = 0x80000000 | (val & ~0x00000001);
-}
-
-static uint32_t pci_unin_config_readl (void *opaque,
- target_phys_addr_t addr)
-{
- PCIBus *s = opaque;
- uint32_t val;
-
- val = (s->config_reg | 0x00000001) & ~0x80000000;
-#ifdef TARGET_WORDS_BIGENDIAN
- val = bswap32(val);
-#endif
-
- return val;
-}
-
-static CPUWriteMemoryFunc *pci_unin_config_write[] = {
- &pci_unin_config_writel,
- &pci_unin_config_writel,
- &pci_unin_config_writel,
-};
-
-static CPUReadMemoryFunc *pci_unin_config_read[] = {
- &pci_unin_config_readl,
- &pci_unin_config_readl,
- &pci_unin_config_readl,
-};
-
-static void pci_unin_writeb (void *opaque, target_phys_addr_t addr,
- uint32_t val)
-{
- PCIBus *s = opaque;
- pci_data_write(s, addr & 3, val, 1);
-}
-
-static void pci_unin_writew (void *opaque, target_phys_addr_t addr,
- uint32_t val)
-{
- PCIBus *s = opaque;
-#ifdef TARGET_WORDS_BIGENDIAN
- val = bswap16(val);
-#endif
- pci_data_write(s, addr & 3, val, 2);
-}
-
-static void pci_unin_writel (void *opaque, target_phys_addr_t addr,
- uint32_t val)
-{
- PCIBus *s = opaque;
-#ifdef TARGET_WORDS_BIGENDIAN
- val = bswap32(val);
-#endif
- pci_data_write(s, addr & 3, val, 4);
-}
-
-static uint32_t pci_unin_readb (void *opaque, target_phys_addr_t addr)
-{
- PCIBus *s = opaque;
- uint32_t val;
-
- val = pci_data_read(s, addr & 3, 1);
-
- return val;
-}
-
-static uint32_t pci_unin_readw (void *opaque, target_phys_addr_t addr)
-{
- PCIBus *s = opaque;
- uint32_t val;
-
- val = pci_data_read(s, addr & 3, 2);
-#ifdef TARGET_WORDS_BIGENDIAN
- val = bswap16(val);
-#endif
-
- return val;
-}
-
-static uint32_t pci_unin_readl (void *opaque, target_phys_addr_t addr)
-{
- PCIBus *s = opaque;
- uint32_t val;
-
- val = pci_data_read(s, addr & 3, 4);
-#ifdef TARGET_WORDS_BIGENDIAN
- val = bswap32(val);
-#endif
-
- return val;
-}
-
-static CPUWriteMemoryFunc *pci_unin_write[] = {
- &pci_unin_writeb,
- &pci_unin_writew,
- &pci_unin_writel,
-};
-
-static CPUReadMemoryFunc *pci_unin_read[] = {
- &pci_unin_readb,
- &pci_unin_readw,
- &pci_unin_readl,
-};
-#endif
-
-static void pmac_set_irq(PCIDevice *d, int irq_num, int level)
-{
- openpic_t *openpic;
- /* XXX: we do not simulate the hardware - we rely on the BIOS to
- set correctly for irq line field */
- openpic = d->bus->openpic;
-#ifdef TARGET_PPC
- if (openpic)
- openpic_set_irq(openpic, d->config[PCI_INTERRUPT_LINE], level);
-#endif
-}
-
-void pci_pmac_set_openpic(PCIBus *bus, openpic_t *openpic)
-{
- bus->openpic = openpic;
-}
-
-PCIBus *pci_pmac_init(void)
-{
- PCIBus *s;
- PCIDevice *d;
- int pci_mem_config, pci_mem_data;
-
- /* Use values found on a real PowerMac */
- /* Uninorth main bus */
- s = pci_register_bus();
- s->set_irq = pmac_set_irq;
-
- pci_mem_config = cpu_register_io_memory(0, pci_unin_main_config_read,
- pci_unin_main_config_write, s);
- pci_mem_data = cpu_register_io_memory(0, pci_unin_main_read,
- pci_unin_main_write, s);
- cpu_register_physical_memory(0xf2800000, 0x1000, pci_mem_config);
- cpu_register_physical_memory(0xf2c00000, 0x1000, pci_mem_data);
- s->devfn_min = 11 << 3;
- d = pci_register_device(s, "Uni-north main", sizeof(PCIDevice),
- 11 << 3, NULL, NULL);
- d->config[0x00] = 0x6b; // vendor_id : Apple
- d->config[0x01] = 0x10;
- d->config[0x02] = 0x1F; // device_id
- d->config[0x03] = 0x00;
- d->config[0x08] = 0x00; // revision
- d->config[0x0A] = 0x00; // class_sub = pci host
- d->config[0x0B] = 0x06; // class_base = PCI_bridge
- d->config[0x0C] = 0x08; // cache_line_size
- d->config[0x0D] = 0x10; // latency_timer
- d->config[0x0E] = 0x00; // header_type
- d->config[0x34] = 0x00; // capabilities_pointer
-
-#if 0 // XXX: not activated as PPC BIOS doesn't handle mutiple buses properly
- /* pci-to-pci bridge */
- d = pci_register_device("Uni-north bridge", sizeof(PCIDevice), 0, 13 << 3,
- NULL, NULL);
- d->config[0x00] = 0x11; // vendor_id : TI
- d->config[0x01] = 0x10;
- d->config[0x02] = 0x26; // device_id
- d->config[0x03] = 0x00;
- d->config[0x08] = 0x05; // revision
- d->config[0x0A] = 0x04; // class_sub = pci2pci
- d->config[0x0B] = 0x06; // class_base = PCI_bridge
- d->config[0x0C] = 0x08; // cache_line_size
- d->config[0x0D] = 0x20; // latency_timer
- d->config[0x0E] = 0x01; // header_type
-
- d->config[0x18] = 0x01; // primary_bus
- d->config[0x19] = 0x02; // secondary_bus
- d->config[0x1A] = 0x02; // subordinate_bus
- d->config[0x1B] = 0x20; // secondary_latency_timer
- d->config[0x1C] = 0x11; // io_base
- d->config[0x1D] = 0x01; // io_limit
- d->config[0x20] = 0x00; // memory_base
- d->config[0x21] = 0x80;
- d->config[0x22] = 0x00; // memory_limit
- d->config[0x23] = 0x80;
- d->config[0x24] = 0x01; // prefetchable_memory_base
- d->config[0x25] = 0x80;
- d->config[0x26] = 0xF1; // prefectchable_memory_limit
- d->config[0x27] = 0x7F;
- // d->config[0x34] = 0xdc // capabilities_pointer
-#endif
-#if 0 // XXX: not needed for now
- /* Uninorth AGP bus */
- s = &pci_bridge[1];
- pci_mem_config = cpu_register_io_memory(0, pci_unin_config_read,
- pci_unin_config_write, s);
- pci_mem_data = cpu_register_io_memory(0, pci_unin_read,
- pci_unin_write, s);
- cpu_register_physical_memory(0xf0800000, 0x1000, pci_mem_config);
- cpu_register_physical_memory(0xf0c00000, 0x1000, pci_mem_data);
-
- d = pci_register_device("Uni-north AGP", sizeof(PCIDevice), 0, 11 << 3,
- NULL, NULL);
- d->config[0x00] = 0x6b; // vendor_id : Apple
- d->config[0x01] = 0x10;
- d->config[0x02] = 0x20; // device_id
- d->config[0x03] = 0x00;
- d->config[0x08] = 0x00; // revision
- d->config[0x0A] = 0x00; // class_sub = pci host
- d->config[0x0B] = 0x06; // class_base = PCI_bridge
- d->config[0x0C] = 0x08; // cache_line_size
- d->config[0x0D] = 0x10; // latency_timer
- d->config[0x0E] = 0x00; // header_type
- // d->config[0x34] = 0x80; // capabilities_pointer
-#endif
-
-#if 0 // XXX: not needed for now
- /* Uninorth internal bus */
- s = &pci_bridge[2];
- pci_mem_config = cpu_register_io_memory(0, pci_unin_config_read,
- pci_unin_config_write, s);
- pci_mem_data = cpu_register_io_memory(0, pci_unin_read,
- pci_unin_write, s);
- cpu_register_physical_memory(0xf4800000, 0x1000, pci_mem_config);
- cpu_register_physical_memory(0xf4c00000, 0x1000, pci_mem_data);
-
- d = pci_register_device("Uni-north internal", sizeof(PCIDevice),
- 3, 11 << 3, NULL, NULL);
- d->config[0x00] = 0x6b; // vendor_id : Apple
- d->config[0x01] = 0x10;
- d->config[0x02] = 0x1E; // device_id
- d->config[0x03] = 0x00;
- d->config[0x08] = 0x00; // revision
- d->config[0x0A] = 0x00; // class_sub = pci host
- d->config[0x0B] = 0x06; // class_base = PCI_bridge
- d->config[0x0C] = 0x08; // cache_line_size
- d->config[0x0D] = 0x10; // latency_timer
- d->config[0x0E] = 0x00; // header_type
- d->config[0x34] = 0x00; // capabilities_pointer
-#endif
-
-#if 0 // Grackle ?
- /* same values as PearPC - check this */
- d->config[0x00] = 0x11; // vendor_id
- d->config[0x01] = 0x10;
- d->config[0x02] = 0x26; // device_id
- d->config[0x03] = 0x00;
- d->config[0x08] = 0x02; // revision
- d->config[0x0a] = 0x04; // class_sub = pci2pci
- d->config[0x0b] = 0x06; // class_base = PCI_bridge
- d->config[0x0e] = 0x01; // header_type
-
- d->config[0x18] = 0x0; // primary_bus
- d->config[0x19] = 0x1; // secondary_bus
- d->config[0x1a] = 0x1; // subordinate_bus
- d->config[0x1c] = 0x10; // io_base
- d->config[0x1d] = 0x20; // io_limit
-
- d->config[0x20] = 0x80; // memory_base
- d->config[0x21] = 0x80;
- d->config[0x22] = 0x90; // memory_limit
- d->config[0x23] = 0x80;
-
- d->config[0x24] = 0x00; // prefetchable_memory_base
- d->config[0x25] = 0x84;
- d->config[0x26] = 0x00; // prefetchable_memory_limit
- d->config[0x27] = 0x85;
-#endif
- return s;
-}
-
-/***********************************************************/
-/* generic PCI irq support */
-
-/* 0 <= irq_num <= 3. level must be 0 or 1 */
-void pci_set_irq(PCIDevice *pci_dev, int irq_num, int level)
-{
- PCIBus *bus = pci_dev->bus;
- bus->set_irq(pci_dev, irq_num, level);
-}
-
-/***********************************************************/
-/* monitor info on PCI */
-
-static void pci_info_device(PCIDevice *d)
-{
- int i, class;
- PCIIORegion *r;
-
- term_printf(" Bus %2d, device %3d, function %d:\n",
- d->bus->bus_num, d->devfn >> 3, d->devfn & 7);
- class = le16_to_cpu(*((uint16_t *)(d->config + PCI_CLASS_DEVICE)));
- term_printf(" ");
- switch(class) {
- case 0x0101:
- term_printf("IDE controller");
- break;
- case 0x0200:
- term_printf("Ethernet controller");
- break;
- case 0x0300:
- term_printf("VGA controller");
- break;
- default:
- term_printf("Class %04x", class);
- break;
- }
- term_printf(": PCI device %04x:%04x\n",
- le16_to_cpu(*((uint16_t *)(d->config + PCI_VENDOR_ID))),
- le16_to_cpu(*((uint16_t *)(d->config + PCI_DEVICE_ID))));
-
- if (d->config[PCI_INTERRUPT_PIN] != 0) {
- term_printf(" IRQ %d.\n", d->config[PCI_INTERRUPT_LINE]);
- }
- for(i = 0;i < PCI_NUM_REGIONS; i++) {
- r = &d->io_regions[i];
- if (r->size != 0) {
- term_printf(" BAR%d: ", i);
- if (r->type & PCI_ADDRESS_SPACE_IO) {
- term_printf("I/O at 0x%04x [0x%04x].\n",
- r->addr, r->addr + r->size - 1);
- } else {
- term_printf("32 bit memory at 0x%08x [0x%08x].\n",
- r->addr, r->addr + r->size - 1);
- }
- }
- }
-}
-
-void pci_info(void)
-{
- PCIBus *bus = first_bus;
- PCIDevice *d;
- int devfn;
-
- if (bus) {
- for(devfn = 0; devfn < 256; devfn++) {
- d = bus->devices[devfn];
- if (d)
- pci_info_device(d);
- }
- }
-}
-
-/***********************************************************/
-/* XXX: the following should be moved to the PC BIOS */
-
-static __attribute__((unused)) uint32_t isa_inb(uint32_t addr)
-{
- return cpu_inb(cpu_single_env, addr);
-}
-
-static void isa_outb(uint32_t val, uint32_t addr)
-{
- cpu_outb(cpu_single_env, addr, val);
-}
-
-static __attribute__((unused)) uint32_t isa_inw(uint32_t addr)
-{
- return cpu_inw(cpu_single_env, addr);
-}
-
-static __attribute__((unused)) void isa_outw(uint32_t val, uint32_t addr)
-{
- cpu_outw(cpu_single_env, addr, val);
-}
-
-static __attribute__((unused)) uint32_t isa_inl(uint32_t addr)
-{
- return cpu_inl(cpu_single_env, addr);
-}
-
-static __attribute__((unused)) void isa_outl(uint32_t val, uint32_t addr)
-{
- cpu_outl(cpu_single_env, addr, val);
-}
-
-static void pci_config_writel(PCIDevice *d, uint32_t addr, uint32_t val)
-{
- PCIBus *s = d->bus;
- s->config_reg = 0x80000000 | (s->bus_num << 16) |
- (d->devfn << 8) | addr;
- pci_data_write(s, 0, val, 4);
-}
-
-static void pci_config_writew(PCIDevice *d, uint32_t addr, uint32_t val)
-{
- PCIBus *s = d->bus;
- s->config_reg = 0x80000000 | (s->bus_num << 16) |
- (d->devfn << 8) | (addr & ~3);
- pci_data_write(s, addr & 3, val, 2);
-}
-
-static void pci_config_writeb(PCIDevice *d, uint32_t addr, uint32_t val)
-{
- PCIBus *s = d->bus;
- s->config_reg = 0x80000000 | (s->bus_num << 16) |
- (d->devfn << 8) | (addr & ~3);
- pci_data_write(s, addr & 3, val, 1);
-}
-
-static __attribute__((unused)) uint32_t pci_config_readl(PCIDevice *d, uint32_t addr)
-{
- PCIBus *s = d->bus;
- s->config_reg = 0x80000000 | (s->bus_num << 16) |
- (d->devfn << 8) | addr;
- return pci_data_read(s, 0, 4);
-}
-
-static uint32_t pci_config_readw(PCIDevice *d, uint32_t addr)
-{
- PCIBus *s = d->bus;
- s->config_reg = 0x80000000 | (s->bus_num << 16) |
- (d->devfn << 8) | (addr & ~3);
- return pci_data_read(s, addr & 3, 2);
-}
-
-static uint32_t pci_config_readb(PCIDevice *d, uint32_t addr)
-{
- PCIBus *s = d->bus;
- s->config_reg = 0x80000000 | (s->bus_num << 16) |
- (d->devfn << 8) | (addr & ~3);
- return pci_data_read(s, addr & 3, 1);
-}
-
-static uint32_t pci_bios_io_addr;
-static uint32_t pci_bios_mem_addr;
-/* host irqs corresponding to PCI irqs A-D */
-static uint8_t pci_irqs[4] = { 10, 11, 10, 11 };
-
-static void pci_set_io_region_addr(PCIDevice *d, int region_num, uint32_t addr)
-{
- PCIIORegion *r;
- uint16_t cmd;
- uint32_t ofs;
-
- if ( region_num == PCI_ROM_SLOT ) {
- ofs = 0x30;
- }else{
- ofs = 0x10 + region_num * 4;
- }
-
- pci_config_writel(d, ofs, addr);
- r = &d->io_regions[region_num];
-
- /* enable memory mappings */
- cmd = pci_config_readw(d, PCI_COMMAND);
- if ( region_num == PCI_ROM_SLOT )
- cmd |= 2;
- else if (r->type & PCI_ADDRESS_SPACE_IO)
- cmd |= 1;
- else
- cmd |= 2;
- pci_config_writew(d, PCI_COMMAND, cmd);
-}
-
-static void pci_bios_init_device(PCIDevice *d)
-{
- int class;
- PCIIORegion *r;
- uint32_t *paddr;
- int i, pin, pic_irq, vendor_id, device_id;
-
- class = pci_config_readw(d, PCI_CLASS_DEVICE);
- vendor_id = pci_config_readw(d, PCI_VENDOR_ID);
- device_id = pci_config_readw(d, PCI_DEVICE_ID);
- switch(class) {
- case 0x0101:
- if (vendor_id == 0x8086 && device_id == 0x7010) {
- /* PIIX3 IDE */
- pci_config_writew(d, 0x40, 0x8000); // enable IDE0
- pci_config_writew(d, 0x42, 0x8000); // enable IDE1
- goto default_map;
- } else {
- /* IDE: we map it as in ISA mode */
- pci_set_io_region_addr(d, 0, 0x1f0);
- pci_set_io_region_addr(d, 1, 0x3f4);
- pci_set_io_region_addr(d, 2, 0x170);
- pci_set_io_region_addr(d, 3, 0x374);
- }
- break;
- case 0x0680:
- if (vendor_id == 0x8086 && device_id == 0x7113) {
- // PIIX4 ACPI PM
- pci_config_writew(d, 0x20, 0x0000); // NO smb bus IO enable in PIIX4
- pci_config_writew(d, 0x22, 0x0000);
- goto default_map;
- }
- break;
-
- case 0x0300:
- if (vendor_id != 0x1234)
- goto default_map;
- /* VGA: map frame buffer to default Bochs VBE address */
- pci_set_io_region_addr(d, 0, 0xE0000000);
- break;
-
- case 0x0800:
- /* PIC */
- vendor_id = pci_config_readw(d, PCI_VENDOR_ID);
- device_id = pci_config_readw(d, PCI_DEVICE_ID);
- if (vendor_id == 0x1014) {
- /* IBM */
- if (device_id == 0x0046 || device_id == 0xFFFF) {
- /* MPIC & MPIC2 */
- pci_set_io_region_addr(d, 0, 0x80800000 + 0x00040000);
- }
- }
- break;
- case 0xff00:
- if (vendor_id == 0x0106b &&
- (device_id == 0x0017 || device_id == 0x0022)) {
- /* macio bridge */
- pci_set_io_region_addr(d, 0, 0x80800000);
- }
- break;
- default:
- default_map:
- /* default memory mappings */
- for(i = 0; i < PCI_NUM_REGIONS; i++) {
- r = &d->io_regions[i];
- if (r->size) {
- if (r->type & PCI_ADDRESS_SPACE_IO)
- paddr = &pci_bios_io_addr;
- else
- paddr = &pci_bios_mem_addr;
- *paddr = (*paddr + r->size - 1) & ~(r->size - 1);
- pci_set_io_region_addr(d, i, *paddr);
- *paddr += r->size;
- }
- }
- break;
- }
-
- /* map the interrupt */
- pin = pci_config_readb(d, PCI_INTERRUPT_PIN);
- if (pin != 0) {
- pin = pci_slot_get_pirq(d, pin - 1);
- pic_irq = pci_irqs[pin];
- pci_config_writeb(d, PCI_INTERRUPT_LINE, pic_irq);
- }
- if (class== 0x0680&& vendor_id == 0x8086 && device_id == 0x7113) {
- // PIIX4 ACPI PM
- pci_config_writew(d, 0x20, 0x0000); // NO smb bus IO enable in PIIX4
- pci_config_writew(d, 0x22, 0x0000);
- pci_config_writew(d, 0x3c, 0x0009); // Hardcodeed IRQ9
- pci_config_writew(d, 0x3d, 0x0001);
- }
-}
-
-/*
- * This function initializes the PCI devices as a normal PCI BIOS
- * would do. It is provided just in case the BIOS has no support for
- * PCI.
- */
-void pci_bios_init(void)
-{
- PCIBus *bus;
- PCIDevice *d;
- int devfn, i, irq;
- uint8_t elcr[2];
-
- pci_bios_io_addr = 0xc000;
- pci_bios_mem_addr = 0xf0000000;
-
- /* activate IRQ mappings */
- elcr[0] = 0x00;
- elcr[1] = 0x00;
- for(i = 0; i < 4; i++) {
- irq = pci_irqs[i];
- /* set to trigger level */
- elcr[irq >> 3] |= (1 << (irq & 7));
- /* activate irq remapping in PIIX */
- pci_config_writeb((PCIDevice *)piix3_state, 0x60 + i, irq);
- }
- isa_outb(elcr[0], 0x4d0);
- isa_outb(elcr[1], 0x4d1);
-
- bus = first_bus;
- if (bus) {
- for(devfn = 0; devfn < 256; devfn++) {
- d = bus->devices[devfn];
- if (d)
- pci_bios_init_device(d);
- }
- }
-}
+++ /dev/null
-/*
- * QEMU PC keyboard emulation
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "vl.h"
-
-/* debug PC keyboard */
-//#define DEBUG_KBD
-
-/* debug PC keyboard : only mouse */
-//#define DEBUG_MOUSE
-
-/* Keyboard Controller Commands */
-#define KBD_CCMD_READ_MODE 0x20 /* Read mode bits */
-#define KBD_CCMD_WRITE_MODE 0x60 /* Write mode bits */
-#define KBD_CCMD_GET_VERSION 0xA1 /* Get controller version */
-#define KBD_CCMD_MOUSE_DISABLE 0xA7 /* Disable mouse interface */
-#define KBD_CCMD_MOUSE_ENABLE 0xA8 /* Enable mouse interface */
-#define KBD_CCMD_TEST_MOUSE 0xA9 /* Mouse interface test */
-#define KBD_CCMD_SELF_TEST 0xAA /* Controller self test */
-#define KBD_CCMD_KBD_TEST 0xAB /* Keyboard interface test */
-#define KBD_CCMD_KBD_DISABLE 0xAD /* Keyboard interface disable */
-#define KBD_CCMD_KBD_ENABLE 0xAE /* Keyboard interface enable */
-#define KBD_CCMD_READ_INPORT 0xC0 /* read input port */
-#define KBD_CCMD_READ_OUTPORT 0xD0 /* read output port */
-#define KBD_CCMD_WRITE_OUTPORT 0xD1 /* write output port */
-#define KBD_CCMD_WRITE_OBUF 0xD2
-#define KBD_CCMD_WRITE_AUX_OBUF 0xD3 /* Write to output buffer as if
- initiated by the auxiliary device */
-#define KBD_CCMD_WRITE_MOUSE 0xD4 /* Write the following byte to the mouse */
-#define KBD_CCMD_DISABLE_A20 0xDD /* HP vectra only ? */
-#define KBD_CCMD_ENABLE_A20 0xDF /* HP vectra only ? */
-#define KBD_CCMD_RESET 0xFE
-
-/* Keyboard Commands */
-#define KBD_CMD_SET_LEDS 0xED /* Set keyboard leds */
-#define KBD_CMD_ECHO 0xEE
-#define KBD_CMD_GET_ID 0xF2 /* get keyboard ID */
-#define KBD_CMD_SET_RATE 0xF3 /* Set typematic rate */
-#define KBD_CMD_ENABLE 0xF4 /* Enable scanning */
-#define KBD_CMD_RESET_DISABLE 0xF5 /* reset and disable scanning */
-#define KBD_CMD_RESET_ENABLE 0xF6 /* reset and enable scanning */
-#define KBD_CMD_RESET 0xFF /* Reset */
-
-/* Keyboard Replies */
-#define KBD_REPLY_POR 0xAA /* Power on reset */
-#define KBD_REPLY_ACK 0xFA /* Command ACK */
-#define KBD_REPLY_RESEND 0xFE /* Command NACK, send the cmd again */
-
-/* Status Register Bits */
-#define KBD_STAT_OBF 0x01 /* Keyboard output buffer full */
-#define KBD_STAT_IBF 0x02 /* Keyboard input buffer full */
-#define KBD_STAT_SELFTEST 0x04 /* Self test successful */
-#define KBD_STAT_CMD 0x08 /* Last write was a command write (0=data) */
-#define KBD_STAT_UNLOCKED 0x10 /* Zero if keyboard locked */
-#define KBD_STAT_MOUSE_OBF 0x20 /* Mouse output buffer full */
-#define KBD_STAT_GTO 0x40 /* General receive/xmit timeout */
-#define KBD_STAT_PERR 0x80 /* Parity error */
-
-/* Controller Mode Register Bits */
-#define KBD_MODE_KBD_INT 0x01 /* Keyboard data generate IRQ1 */
-#define KBD_MODE_MOUSE_INT 0x02 /* Mouse data generate IRQ12 */
-#define KBD_MODE_SYS 0x04 /* The system flag (?) */
-#define KBD_MODE_NO_KEYLOCK 0x08 /* The keylock doesn't affect the keyboard if set */
-#define KBD_MODE_DISABLE_KBD 0x10 /* Disable keyboard interface */
-#define KBD_MODE_DISABLE_MOUSE 0x20 /* Disable mouse interface */
-#define KBD_MODE_KCC 0x40 /* Scan code conversion to PC format */
-#define KBD_MODE_RFU 0x80
-
-/* Mouse Commands */
-#define AUX_SET_SCALE11 0xE6 /* Set 1:1 scaling */
-#define AUX_SET_SCALE21 0xE7 /* Set 2:1 scaling */
-#define AUX_SET_RES 0xE8 /* Set resolution */
-#define AUX_GET_SCALE 0xE9 /* Get scaling factor */
-/* according to Synaptic docs this $E9 is really 3-byte status */
-#define AUX_SET_STREAM 0xEA /* Set stream mode */
-#define AUX_POLL 0xEB /* Poll */
-#define AUX_RESET_WRAP 0xEC /* Reset wrap mode */
-#define AUX_SET_WRAP 0xEE /* Set wrap mode */
-#define AUX_SET_REMOTE 0xF0 /* Set remote mode */
-#define AUX_GET_TYPE 0xF2 /* Get type */
-#define AUX_SET_SAMPLE 0xF3 /* Set sample rate */
-#define AUX_ENABLE_DEV 0xF4 /* Enable aux device */
-#define AUX_DISABLE_DEV 0xF5 /* Disable aux device */
-#define AUX_SET_DEFAULT 0xF6
-#define AUX_RESET 0xFF /* Reset aux device */
-#define AUX_ACK 0xFA /* Command byte ACK. */
-
-#define MOUSE_STATUS_REMOTE 0x40
-#define MOUSE_STATUS_ENABLED 0x20
-#define MOUSE_STATUS_SCALE21 0x10
-
-#define KBD_QUEUE_SIZE 256
-
-/*
- * Summagraphics tablet defines
- */
-#define SUMMA_BORDER 100
-#define SUMMA_MAXX (16000 - 1)
-#define SUMMA_MAXY (16000 - 1)
-
-#define MAX_ABSX 0x7fff
-#define MAX_ABSY 0x7fff
-
-typedef struct {
- uint8_t aux[KBD_QUEUE_SIZE];
- uint8_t data[KBD_QUEUE_SIZE];
- int rptr, wptr, count;
-} KBDQueue;
-
-/*
- * Mouse types
- */
-#define PS2 0
-#define IMPS2 3
-#define IMEX 4
-#define PAD 10
-#define TABLET 11
-
-typedef struct KBDState {
- KBDQueue queue;
- uint8_t write_cmd; /* if non zero, write data to port 60 is expected */
- uint8_t status;
- uint8_t mode;
- /* keyboard state */
- int kbd_write_cmd;
- int scan_enabled;
- /* mouse state */
- int mouse_write_cmd;
- uint8_t mouse_status;
- uint8_t mouse_resolution;
- uint8_t mouse_sample_rate;
- uint8_t mouse_wrap;
- uint8_t mouse_type; /* 0 = PS2, 3 = IMPS/2, 4 = IMEX */
- uint8_t mouse_detect_state;
- int mouse_dx; /* current values, needed for 'poll' mode */
- int mouse_dy;
- int mouse_dz;
- uint8_t mouse_buttons;
- CharDriverState *chr;
- SerialState *serial;
-} KBDState;
-
-KBDState kbd_state;
-
-#define MODE_STREAM_SWITCH 0
-#define MODE_STREAM 1
-#define MODE_REMOTE 2
-#define MODE_POINT 3
-
-#define ORIGIN_LOWER_LEFT 0
-#define ORIGIN_UPPER_LEFT 1
-
-struct SummaState {
- int report_mode;
- int origin;
-} SummaState;
-
-int summa_ok; /* Allow Summagraphics emulation if true */
-
-/* update irq and KBD_STAT_[MOUSE_]OBF */
-/* XXX: not generating the irqs if KBD_MODE_DISABLE_KBD is set may be
- incorrect, but it avoids having to simulate exact delays */
-static void kbd_update_irq(KBDState *s)
-{
- KBDQueue *q = &s->queue;
- int irq12_level, irq1_level;
-
- irq1_level = 0;
- irq12_level = 0;
- s->status &= ~(KBD_STAT_OBF | KBD_STAT_MOUSE_OBF);
- if (q->count != 0) {
- s->status |= KBD_STAT_OBF;
- if (q->aux[q->rptr]) {
- s->status |= KBD_STAT_MOUSE_OBF;
- if (s->mode & KBD_MODE_MOUSE_INT)
- irq12_level = 1;
- } else {
- if ((s->mode & KBD_MODE_KBD_INT) &&
- !(s->mode & KBD_MODE_DISABLE_KBD))
- irq1_level = 1;
- }
- }
- pic_set_irq(1, irq1_level);
- pic_set_irq(12, irq12_level);
-}
-
-static void kbd_queue(KBDState *s, int b, int aux)
-{
- KBDQueue *q = &s->queue;
-
-#if defined(DEBUG_MOUSE) || defined(DEBUG_KBD)
- if (aux)
- printf("mouse event: 0x%02x\n", b);
-#ifdef DEBUG_KBD
- else
- printf("kbd event: 0x%02x\n", b);
-#endif
-#endif
- if (q->count >= KBD_QUEUE_SIZE)
- return;
- q->aux[q->wptr] = aux;
- q->data[q->wptr] = b;
- if (++q->wptr == KBD_QUEUE_SIZE)
- q->wptr = 0;
- q->count++;
- kbd_update_irq(s);
-}
-
-static void pc_kbd_put_keycode(void *opaque, int keycode)
-{
- KBDState *s = opaque;
- kbd_queue(s, keycode, 0);
-}
-
-static uint32_t kbd_read_status(void *opaque, uint32_t addr)
-{
- KBDState *s = opaque;
- int val;
- val = s->status;
-#if defined(DEBUG_KBD)
- printf("kbd: read status=0x%02x\n", val);
-#endif
- return val;
-}
-
-static void kbd_write_command(void *opaque, uint32_t addr, uint32_t val)
-{
- KBDState *s = opaque;
-
-#ifdef DEBUG_KBD
- printf("kbd: write cmd=0x%02x\n", val);
-#endif
- switch(val) {
- case KBD_CCMD_READ_MODE:
- kbd_queue(s, s->mode, 0);
- break;
- case KBD_CCMD_WRITE_MODE:
- case KBD_CCMD_WRITE_OBUF:
- case KBD_CCMD_WRITE_AUX_OBUF:
- case KBD_CCMD_WRITE_MOUSE:
- case KBD_CCMD_WRITE_OUTPORT:
- s->write_cmd = val;
- break;
- case KBD_CCMD_MOUSE_DISABLE:
- s->mode |= KBD_MODE_DISABLE_MOUSE;
- break;
- case KBD_CCMD_MOUSE_ENABLE:
- s->mode &= ~KBD_MODE_DISABLE_MOUSE;
- break;
- case KBD_CCMD_TEST_MOUSE:
- kbd_queue(s, 0x00, 0);
- break;
- case KBD_CCMD_SELF_TEST:
- s->status |= KBD_STAT_SELFTEST;
- kbd_queue(s, 0x55, 0);
- break;
- case KBD_CCMD_KBD_TEST:
- kbd_queue(s, 0x00, 0);
- break;
- case KBD_CCMD_KBD_DISABLE:
- s->mode |= KBD_MODE_DISABLE_KBD;
- kbd_update_irq(s);
- break;
- case KBD_CCMD_KBD_ENABLE:
- s->mode &= ~KBD_MODE_DISABLE_KBD;
- kbd_update_irq(s);
- break;
- case KBD_CCMD_READ_INPORT:
- kbd_queue(s, 0x00, 0);
- break;
- case KBD_CCMD_READ_OUTPORT:
- /* XXX: check that */
-#ifdef TARGET_I386
- val = 0x01 | (((cpu_single_env->a20_mask >> 20) & 1) << 1);
-#else
- val = 0x01;
-#endif
- if (s->status & KBD_STAT_OBF)
- val |= 0x10;
- if (s->status & KBD_STAT_MOUSE_OBF)
- val |= 0x20;
- kbd_queue(s, val, 0);
- break;
-#ifdef TARGET_I386
- case KBD_CCMD_ENABLE_A20:
- cpu_x86_set_a20(cpu_single_env, 1);
- break;
- case KBD_CCMD_DISABLE_A20:
- cpu_x86_set_a20(cpu_single_env, 0);
- break;
-#endif
- case KBD_CCMD_RESET:
- qemu_system_reset_request();
- break;
- case 0xff:
- /* ignore that - I don't know what is its use */
- break;
- default:
- fprintf(stderr, "qemu: unsupported keyboard cmd=0x%02x\n", val);
- break;
- }
-}
-
-static uint32_t kbd_read_data(void *opaque, uint32_t addr)
-{
- KBDState *s = opaque;
- KBDQueue *q;
- int val, index, aux;
-
- q = &s->queue;
- if (q->count == 0) {
- /* NOTE: if no data left, we return the last keyboard one
- (needed for EMM386) */
- /* XXX: need a timer to do things correctly */
- index = q->rptr - 1;
- if (index < 0)
- index = KBD_QUEUE_SIZE - 1;
- val = q->data[index];
- } else {
- aux = q->aux[q->rptr];
- val = q->data[q->rptr];
- if (++q->rptr == KBD_QUEUE_SIZE)
- q->rptr = 0;
- q->count--;
- /* reading deasserts IRQ */
- if (aux)
- pic_set_irq(12, 0);
- else
- pic_set_irq(1, 0);
- }
- /* reassert IRQs if data left */
- kbd_update_irq(s);
-#ifdef DEBUG_KBD
- printf("kbd: read data=0x%02x\n", val);
-#endif
- return val;
-}
-
-static void kbd_reset_keyboard(KBDState *s)
-{
- s->scan_enabled = 1;
-}
-
-static void kbd_write_keyboard(KBDState *s, int val)
-{
- switch(s->kbd_write_cmd) {
- default:
- case -1:
- switch(val) {
- case 0x00:
- kbd_queue(s, KBD_REPLY_ACK, 0);
- break;
- case 0x05:
- kbd_queue(s, KBD_REPLY_RESEND, 0);
- break;
- case KBD_CMD_GET_ID:
- kbd_queue(s, KBD_REPLY_ACK, 0);
- kbd_queue(s, 0xab, 0);
- kbd_queue(s, 0x83, 0);
- break;
- case KBD_CMD_ECHO:
- kbd_queue(s, KBD_CMD_ECHO, 0);
- break;
- case KBD_CMD_ENABLE:
- s->scan_enabled = 1;
- kbd_queue(s, KBD_REPLY_ACK, 0);
- break;
- case KBD_CMD_SET_LEDS:
- case KBD_CMD_SET_RATE:
- s->kbd_write_cmd = val;
- kbd_queue(s, KBD_REPLY_ACK, 0);
- break;
- case KBD_CMD_RESET_DISABLE:
- kbd_reset_keyboard(s);
- s->scan_enabled = 0;
- kbd_queue(s, KBD_REPLY_ACK, 0);
- break;
- case KBD_CMD_RESET_ENABLE:
- kbd_reset_keyboard(s);
- s->scan_enabled = 1;
- kbd_queue(s, KBD_REPLY_ACK, 0);
- break;
- case KBD_CMD_RESET:
- kbd_reset_keyboard(s);
- kbd_queue(s, KBD_REPLY_ACK, 0);
- kbd_queue(s, KBD_REPLY_POR, 0);
- break;
- default:
- kbd_queue(s, KBD_REPLY_ACK, 0);
- break;
- }
- break;
- case KBD_CMD_SET_LEDS:
- kbd_queue(s, KBD_REPLY_ACK, 0);
- s->kbd_write_cmd = -1;
- break;
- case KBD_CMD_SET_RATE:
- kbd_queue(s, KBD_REPLY_ACK, 0);
- s->kbd_write_cmd = -1;
- break;
- }
-}
-
-int mouse_maxx, mouse_maxy;
-
-static void kbd_mouse_send_packet(KBDState *s)
-{
- unsigned int b;
- int dx1, dy1, dz1;
-
- dx1 = s->mouse_dx;
- dy1 = s->mouse_dy;
- dz1 = s->mouse_dz;
- /* XXX: increase range to 8 bits ? */
- if (dx1 > 127)
- dx1 = 127;
- else if (dx1 < -127)
- dx1 = -127;
- if (dy1 > 127)
- dy1 = 127;
- else if (dy1 < -127)
- dy1 = -127;
- b = 0x08 | ((dx1 < 0) << 4) | ((dy1 < 0) << 5) | (s->mouse_buttons & 0x07);
- kbd_queue(s, b, 1);
- kbd_queue(s, dx1 & 0xff, 1);
- kbd_queue(s, dy1 & 0xff, 1);
- /* extra byte for IMPS/2 or IMEX */
- switch(s->mouse_type) {
- default:
- break;
- case IMPS2:
- if (dz1 > 127)
- dz1 = 127;
- else if (dz1 < -127)
- dz1 = -127;
- kbd_queue(s, dz1 & 0xff, 1);
- break;
- case IMEX:
- if (dz1 > 7)
- dz1 = 7;
- else if (dz1 < -7)
- dz1 = -7;
- b = (dz1 & 0x0f) | ((s->mouse_buttons & 0x18) << 1);
- kbd_queue(s, b, 1);
- break;
- }
-
- /* update deltas */
- s->mouse_dx -= dx1;
- s->mouse_dy -= dy1;
- s->mouse_dz -= dz1;
-}
-
-static void summa_mouse_event(void *opaque, int x, int y, int z, int buttons_state)
-{
- KBDState *s = opaque;
-
- if (SummaState.report_mode == MODE_STREAM) {
- if (SummaState.origin == ORIGIN_LOWER_LEFT)
- y = mouse_maxy - y;
- x = ((x * SUMMA_MAXX) / MAX_ABSX) + SUMMA_BORDER;
- y = ((y * SUMMA_MAXY) / MAX_ABSY) + SUMMA_BORDER;
-fprintf(stderr, "summa_mouse_event: x, y - %d, %d\n", x, y);
- ser_queue(s->serial, 0x80 | (buttons_state & 7));
- ser_queue(s->serial, x & 0x7f);
- ser_queue(s->serial, x >> 7);
- ser_queue(s->serial, y & 0x7f);
- ser_queue(s->serial, y >> 7);
- }
- return;
-}
-
-static void summa(KBDState *s, uint8_t val)
-{
- static int zflg = 0;
-
- if (zflg) {
- zflg = 0;
- switch (val) {
-
- case 'b': /* binary report mode */
- break;
-
- case 't': /* stylus type - we do 4 button cursor */
- ser_queue(s->serial, 'C');
- ser_queue(s->serial, 'S');
- ser_queue(s->serial, 'R');
- ser_queue(s->serial, '4');
- ser_queue(s->serial, '\r');
- break;
-
- }
- return;
- }
- zflg = 0;
-
- switch (val) {
-
- case 'B': /* point mode */
- /* This is supposed to be `set to point mode' but the Linux driver
- * is broken and incorrectly sends a reset command (somebody
- * needs to learn that the address 0 does not necessarily contain
- * a zero). This is the first valid command that Linux sends
- * out so we'll treat it as a reset
- */
- case '\0': /* reset */
- s->mouse_type = TABLET;
- s->mouse_status |= MOUSE_STATUS_ENABLED;
- SummaState.origin = ORIGIN_LOWER_LEFT;
- SummaState.report_mode = (val == 'B') ? MODE_POINT : MODE_STREAM_SWITCH;
- qemu_add_mouse_event_handler(summa_mouse_event, s, 1);
- break;
-
- case 'z': /* start of 2 byte command */
- zflg++;
- break;
-
- case 'x': /* code check */
- /*
- * Return checksum
- */
- ser_queue(s->serial, '.');
- ser_queue(s->serial, '#');
- ser_queue(s->serial, '1');
- ser_queue(s->serial, '2');
- ser_queue(s->serial, '3');
- ser_queue(s->serial, '4');
- break;
-
- case '?': /* read firmware ID */
- ser_queue(s->serial, '0');
- break;
-
- case 'a': /* read config */
- /*
- * Config looks like a movement packet but, because of scaling
- * issues we can't use `kbd_send_packet' to do this.
- */
- ser_queue(s->serial, 0x94);
- ser_queue(s->serial, (SUMMA_MAXX & 0x7f));
- ser_queue(s->serial, (SUMMA_MAXX >> 7));
- ser_queue(s->serial, (SUMMA_MAXY & 0x7f));
- ser_queue(s->serial, (SUMMA_MAXY >> 7));
- break;
-
- case 'b': /* origin at upper left */
- SummaState.origin = ORIGIN_UPPER_LEFT;
- break;
-
- case 'c': /* origin at lower left */
- SummaState.origin = ORIGIN_LOWER_LEFT;
- break;
-
- case '@': /* stream mode */
- SummaState.report_mode = MODE_STREAM;
- break;
-
- case 'D': /* remote request mode */
- SummaState.report_mode = MODE_REMOTE;
- break;
-
- case 'P': /* trigger, e.g. send report now */
- case 'R': /* report rate = max/2 */
- default: /* ignore all others */
- break;
-
- }
-
- return;
-}
-
-int summa_write(CharDriverState *chr, const uint8_t *buf, int len)
-{
- KBDState *s = (KBDState *)chr->opaque;
- int n;
-
- n = len;
- while (n-- > 0)
- summa(s, *buf++);
- return len;
-}
-
-void summa_init(SerialState *serial, CharDriverState *chr)
-{
-
- if (summa_ok == 0)
- return;
- kbd_state.chr = chr;
- kbd_state.serial = serial;
- chr->chr_write = summa_write;
- chr->opaque = (void *)&kbd_state;
- return;
-}
-
-static void pc_kbd_mouse_event(void *opaque,
- int dx, int dy, int dz, int buttons_state)
-{
- KBDState *s = opaque;
-
- /* check if deltas are recorded when disabled */
- if (!(s->mouse_status & MOUSE_STATUS_ENABLED))
- return;
-
- s->mouse_dx += dx;
- s->mouse_dy -= dy;
- s->mouse_dz += dz;
- /* XXX: SDL sometimes generates nul events: we delete them */
- if (s->mouse_dx == 0 && s->mouse_dy == 0 && s->mouse_dz == 0 &&
- s->mouse_buttons == buttons_state)
- return;
- s->mouse_buttons = buttons_state;
-
- if (!(s->mouse_status & MOUSE_STATUS_REMOTE) &&
- (s->queue.count < (KBD_QUEUE_SIZE - 16))) {
- for(;;) {
- /* if not remote, send event. Multiple events are sent if
- too big deltas */
- kbd_mouse_send_packet(s);
- if (s->mouse_dx == 0 && s->mouse_dy == 0 && s->mouse_dz == 0)
- break;
- }
- }
-}
-
-static void kbd_write_mouse(KBDState *s, int val)
-{
-#ifdef DEBUG_MOUSE
- printf("kbd: write mouse 0x%02x\n", val);
-#endif
- switch(s->mouse_write_cmd) {
- default:
- case -1:
- /* mouse command */
- if (s->mouse_wrap) {
- if (val == AUX_RESET_WRAP) {
- s->mouse_wrap = 0;
- kbd_queue(s, AUX_ACK, 1);
- return;
- } else if (val != AUX_RESET) {
- kbd_queue(s, val, 1);
- return;
- }
- }
- switch(val) {
- case AUX_SET_SCALE11:
- s->mouse_status &= ~MOUSE_STATUS_SCALE21;
- kbd_queue(s, AUX_ACK, 1);
- break;
- case AUX_SET_SCALE21:
- s->mouse_status |= MOUSE_STATUS_SCALE21;
- kbd_queue(s, AUX_ACK, 1);
- break;
- case AUX_SET_STREAM:
- s->mouse_status &= ~MOUSE_STATUS_REMOTE;
- kbd_queue(s, AUX_ACK, 1);
- break;
- case AUX_SET_WRAP:
- s->mouse_wrap = 1;
- kbd_queue(s, AUX_ACK, 1);
- break;
- case AUX_SET_REMOTE:
- s->mouse_status |= MOUSE_STATUS_REMOTE;
- kbd_queue(s, AUX_ACK, 1);
- break;
- case AUX_GET_TYPE:
- kbd_queue(s, AUX_ACK, 1);
- kbd_queue(s, s->mouse_type, 1);
- break;
- case AUX_SET_RES:
- case AUX_SET_SAMPLE:
- s->mouse_write_cmd = val;
- kbd_queue(s, AUX_ACK, 1);
- break;
- case AUX_GET_SCALE:
- {
- /* not a special command, just do the regular stuff */
- kbd_queue(s, AUX_ACK, 1);
- kbd_queue(s, s->mouse_status, 1);
- kbd_queue(s, s->mouse_resolution, 1);
- kbd_queue(s, s->mouse_sample_rate, 1);
- }
- break;
- case AUX_POLL:
- kbd_queue(s, AUX_ACK, 1);
- kbd_mouse_send_packet(s);
- break;
- case AUX_ENABLE_DEV:
- s->mouse_status |= MOUSE_STATUS_ENABLED;
- kbd_queue(s, AUX_ACK, 1);
- break;
- case AUX_DISABLE_DEV:
- s->mouse_status &= ~MOUSE_STATUS_ENABLED;
- kbd_queue(s, AUX_ACK, 1);
- break;
- case AUX_SET_DEFAULT:
- s->mouse_sample_rate = 100;
- s->mouse_resolution = 2;
- s->mouse_status = 0;
- kbd_queue(s, AUX_ACK, 1);
- break;
- case AUX_RESET:
- s->mouse_sample_rate = 100;
- s->mouse_resolution = 2;
- s->mouse_status = 0;
- kbd_queue(s, AUX_ACK, 1);
- kbd_queue(s, 0xaa, 1);
- kbd_queue(s, s->mouse_type, 1);
- break;
- default:
- break;
- }
- break;
- case AUX_SET_SAMPLE:
- s->mouse_sample_rate = val;
-#if 0
- /* detect IMPS/2 or IMEX */
- switch(s->mouse_detect_state) {
- default:
- case 0:
- if (val == 200)
- s->mouse_detect_state = 1;
- break;
- case 1:
- if (val == 100)
- s->mouse_detect_state = 2;
- else if (val == 200)
- s->mouse_detect_state = 3;
- else
- s->mouse_detect_state = 0;
- break;
- case 2:
- if (val == 80)
- s->mouse_type = IMPS2; /* IMPS/2 */
- s->mouse_detect_state = 0;
- break;
- case 3:
- if (val == 80)
- s->mouse_type = IMEX; /* IMEX */
- s->mouse_detect_state = 0;
- break;
- }
-#endif
- kbd_queue(s, AUX_ACK, 1);
- s->mouse_write_cmd = -1;
- break;
- case AUX_SET_RES:
- s->mouse_resolution = val;
- kbd_queue(s, AUX_ACK, 1);
- s->mouse_write_cmd = -1;
- break;
- }
-}
-
-void kbd_write_data(void *opaque, uint32_t addr, uint32_t val)
-{
- KBDState *s = opaque;
-
-#ifdef DEBUG_KBD
- printf("kbd: write data=0x%02x\n", val);
-#endif
-
- switch(s->write_cmd) {
- case 0:
- kbd_write_keyboard(s, val);
- break;
- case KBD_CCMD_WRITE_MODE:
- s->mode = val;
- kbd_update_irq(s);
- break;
- case KBD_CCMD_WRITE_OBUF:
- kbd_queue(s, val, 0);
- break;
- case KBD_CCMD_WRITE_AUX_OBUF:
- kbd_queue(s, val, 1);
- break;
- case KBD_CCMD_WRITE_OUTPORT:
-#ifdef TARGET_I386
- cpu_x86_set_a20(cpu_single_env, (val >> 1) & 1);
-#endif
- if (!(val & 1)) {
- qemu_system_reset_request();
- }
- break;
- case KBD_CCMD_WRITE_MOUSE:
- kbd_write_mouse(s, val);
- break;
- default:
- break;
- }
- s->write_cmd = 0;
-}
-
-static void kbd_reset(void *opaque)
-{
- KBDState *s = opaque;
- KBDQueue *q;
-
- s->kbd_write_cmd = -1;
- s->mouse_write_cmd = -1;
- s->mode = KBD_MODE_KBD_INT | KBD_MODE_MOUSE_INT | KBD_MODE_KCC;
- s->status = KBD_STAT_CMD | KBD_STAT_UNLOCKED;
- q = &s->queue;
- q->rptr = 0;
- q->wptr = 0;
- q->count = 0;
-}
-
-static void kbd_save(QEMUFile* f, void* opaque)
-{
- KBDState *s = (KBDState*)opaque;
-
- qemu_put_8s(f, &s->write_cmd);
- qemu_put_8s(f, &s->status);
- qemu_put_8s(f, &s->mode);
- qemu_put_be32s(f, (uint32_t *)&s->kbd_write_cmd);
- qemu_put_be32s(f, (uint32_t *)&s->scan_enabled);
- qemu_put_be32s(f, (uint32_t *)&s->mouse_write_cmd);
- qemu_put_8s(f, &s->mouse_status);
- qemu_put_8s(f, &s->mouse_resolution);
- qemu_put_8s(f, &s->mouse_sample_rate);
- qemu_put_8s(f, &s->mouse_wrap);
- qemu_put_8s(f, &s->mouse_type);
- qemu_put_8s(f, &s->mouse_detect_state);
- qemu_put_be32s(f, (uint32_t *)&s->mouse_dx);
- qemu_put_be32s(f, (uint32_t *)&s->mouse_dy);
- qemu_put_be32s(f, (uint32_t *)&s->mouse_dz);
- qemu_put_8s(f, &s->mouse_buttons);
-}
-
-static int kbd_load(QEMUFile* f, void* opaque, int version_id)
-{
- KBDState *s = (KBDState*)opaque;
-
- if (version_id != 2)
- return -EINVAL;
- qemu_get_8s(f, &s->write_cmd);
- qemu_get_8s(f, &s->status);
- qemu_get_8s(f, &s->mode);
- qemu_get_be32s(f, (uint32_t *)&s->kbd_write_cmd);
- qemu_get_be32s(f, (uint32_t *)&s->scan_enabled);
- qemu_get_be32s(f, (uint32_t *)&s->mouse_write_cmd);
- qemu_get_8s(f, &s->mouse_status);
- qemu_get_8s(f, &s->mouse_resolution);
- qemu_get_8s(f, &s->mouse_sample_rate);
- qemu_get_8s(f, &s->mouse_wrap);
- qemu_get_8s(f, &s->mouse_type);
- qemu_get_8s(f, &s->mouse_detect_state);
- qemu_get_be32s(f, (uint32_t *)&s->mouse_dx);
- qemu_get_be32s(f, (uint32_t *)&s->mouse_dy);
- qemu_get_be32s(f, (uint32_t *)&s->mouse_dz);
- qemu_get_8s(f, &s->mouse_buttons);
- return 0;
-}
-
-void kbd_init(void)
-{
- KBDState *s = &kbd_state;
-
- s->mouse_type = PS2;
- kbd_reset(s);
- register_savevm("pckbd", 0, 2, kbd_save, kbd_load, s);
- register_ioport_read(0x60, 1, 1, kbd_read_data, s);
- register_ioport_write(0x60, 1, 1, kbd_write_data, s);
- register_ioport_read(0x64, 1, 1, kbd_read_status, s);
- register_ioport_write(0x64, 1, 1, kbd_write_command, s);
-
- qemu_add_kbd_event_handler(pc_kbd_put_keycode, s);
- qemu_add_mouse_event_handler(pc_kbd_mouse_event, s, 0);
- qemu_register_reset(kbd_reset, s);
-}
+++ /dev/null
-/*
- * QEMU AMD PC-Net II (Am79C970A) emulation
- *
- * Copyright (c) 2004 Antony T Curtis
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-/* This software was written to be compatible with the specification:
- * AMD Am79C970A PCnet-PCI II Ethernet Controller Data-Sheet
- * AMD Publication# 19436 Rev:E Amendment/0 Issue Date: June 2000
- */
-
-#include "vl.h"
-#include <sys/times.h>
-#include <arpa/inet.h>
-#include <net/ethernet.h>
-
-//#define PCNET_DEBUG
-//#define PCNET_DEBUG_IO
-//#define PCNET_DEBUG_BCR
-//#define PCNET_DEBUG_CSR
-//#define PCNET_DEBUG_RMD
-//#define PCNET_DEBUG_TMD
-//#define PCNET_DEBUG_MATCH
-
-
-#define PCNET_IOPORT_SIZE 0x20
-#define PCNET_PNPMMIO_SIZE 0x20
-
-
-#include "pcnet.h"
-
-static void pcnet_poll(PCNetState *s);
-static void pcnet_poll_timer(void *opaque);
-
-static uint32_t pcnet_csr_readw(PCNetState *s, uint32_t rap);
-static void pcnet_csr_writew(PCNetState *s, uint32_t rap, uint32_t new_value);
-static void pcnet_bcr_writew(PCNetState *s, uint32_t rap, uint32_t val);
-static uint32_t pcnet_bcr_readw(PCNetState *s, uint32_t rap);
-
-static void pcnet_s_reset(PCNetState *s)
-{
-#ifdef PCNET_DEBUG
- printf("pcnet_s_reset\n");
-#endif
-
- s->lnkst = 0x40;
- s->rdra = 0;
- s->tdra = 0;
- s->rap = 0;
-
- s->bcr[BCR_BSBC] &= ~0x0080;
-
- s->csr[0] = 0x0004;
- s->csr[3] = 0x0000;
- s->csr[4] = 0x0115;
- s->csr[5] = 0x0000;
- s->csr[6] = 0x0000;
- s->csr[8] = 0;
- s->csr[9] = 0;
- s->csr[10] = 0;
- s->csr[11] = 0;
- s->csr[12] = le16_to_cpu(((uint16_t *)&s->prom[0])[0]);
- s->csr[13] = le16_to_cpu(((uint16_t *)&s->prom[0])[1]);
- s->csr[14] = le16_to_cpu(((uint16_t *)&s->prom[0])[2]);
- s->csr[15] &= 0x21c4;
- s->csr[72] = 1;
- s->csr[74] = 1;
- s->csr[76] = 1;
- s->csr[78] = 1;
- s->csr[80] = 0x1410;
- s->csr[88] = 0x1003;
- s->csr[89] = 0x0262;
- s->csr[94] = 0x0000;
- s->csr[100] = 0x0200;
- s->csr[103] = 0x0105;
- s->csr[103] = 0x0105;
- s->csr[112] = 0x0000;
- s->csr[114] = 0x0000;
- s->csr[122] = 0x0000;
- s->csr[124] = 0x0000;
-}
-
-static void pcnet_update_irq(PCNetState *s)
-{
- int isr = 0;
- s->csr[0] &= ~0x0080;
-
-#if 1
- if (((s->csr[0] & ~s->csr[3]) & 0x5f00) ||
- (((s->csr[4]>>1) & ~s->csr[4]) & 0x0115) ||
- (((s->csr[5]>>1) & s->csr[5]) & 0x0048))
-#else
- if ((!(s->csr[3] & 0x4000) && !!(s->csr[0] & 0x4000)) /* BABL */ ||
- (!(s->csr[3] & 0x1000) && !!(s->csr[0] & 0x1000)) /* MISS */ ||
- (!(s->csr[3] & 0x0100) && !!(s->csr[0] & 0x0100)) /* IDON */ ||
- (!(s->csr[3] & 0x0200) && !!(s->csr[0] & 0x0200)) /* TINT */ ||
- (!(s->csr[3] & 0x0400) && !!(s->csr[0] & 0x0400)) /* RINT */ ||
- (!(s->csr[3] & 0x0800) && !!(s->csr[0] & 0x0800)) /* MERR */ ||
- (!(s->csr[4] & 0x0001) && !!(s->csr[4] & 0x0002)) /* JAB */ ||
- (!(s->csr[4] & 0x0004) && !!(s->csr[4] & 0x0008)) /* TXSTRT */ ||
- (!(s->csr[4] & 0x0010) && !!(s->csr[4] & 0x0020)) /* RCVO */ ||
- (!(s->csr[4] & 0x0100) && !!(s->csr[4] & 0x0200)) /* MFCO */ ||
- (!!(s->csr[5] & 0x0040) && !!(s->csr[5] & 0x0080)) /* EXDINT */ ||
- (!!(s->csr[5] & 0x0008) && !!(s->csr[5] & 0x0010)) /* MPINT */)
-#endif
- {
-
- isr = CSR_INEA(s);
- s->csr[0] |= 0x0080;
- }
-
- if (!!(s->csr[4] & 0x0080) && CSR_INEA(s)) { /* UINT */
- s->csr[4] &= ~0x0080;
- s->csr[4] |= 0x0040;
- s->csr[0] |= 0x0080;
- isr = 1;
-#ifdef PCNET_DEBUG
- printf("pcnet user int\n");
-#endif
- }
-
-#if 1
- if (((s->csr[5]>>1) & s->csr[5]) & 0x0500)
-#else
- if ((!!(s->csr[5] & 0x0400) && !!(s->csr[5] & 0x0800)) /* SINT */ ||
- (!!(s->csr[5] & 0x0100) && !!(s->csr[5] & 0x0200)) /* SLPINT */ )
-#endif
- {
- isr = 1;
- s->csr[0] |= 0x0080;
- }
-
- if (isr != s->isr) {
-#ifdef PCNET_DEBUG
- printf("pcnet: INTA=%d\n", isr);
-#endif
- }
- pci_set_irq(&s->dev, 0, isr);
- s->isr = isr;
-}
-
-static void pcnet_init(PCNetState *s)
-{
-#ifdef PCNET_DEBUG
- printf("pcnet_init init_addr=0x%08x\n", PHYSADDR(s,CSR_IADR(s)));
-#endif
-
-#define PCNET_INIT() do { \
- cpu_physical_memory_read(PHYSADDR(s,CSR_IADR(s)), \
- (uint8_t *)&initblk, sizeof(initblk)); \
- s->csr[15] = le16_to_cpu(initblk.mode); \
- CSR_RCVRL(s) = (initblk.rlen < 9) ? (1 << initblk.rlen) : 512; \
- CSR_XMTRL(s) = (initblk.tlen < 9) ? (1 << initblk.tlen) : 512; \
- s->csr[ 6] = (initblk.tlen << 12) | (initblk.rlen << 8); \
- s->csr[ 8] = le16_to_cpu(initblk.ladrf1); \
- s->csr[ 9] = le16_to_cpu(initblk.ladrf2); \
- s->csr[10] = le16_to_cpu(initblk.ladrf3); \
- s->csr[11] = le16_to_cpu(initblk.ladrf4); \
- s->csr[12] = le16_to_cpu(initblk.padr1); \
- s->csr[13] = le16_to_cpu(initblk.padr2); \
- s->csr[14] = le16_to_cpu(initblk.padr3); \
- s->rdra = PHYSADDR(s,initblk.rdra); \
- s->tdra = PHYSADDR(s,initblk.tdra); \
-} while (0)
-
- if (BCR_SSIZE32(s)) {
- struct pcnet_initblk32 initblk;
- PCNET_INIT();
-#ifdef PCNET_DEBUG
- printf("initblk.rlen=0x%02x, initblk.tlen=0x%02x\n",
- initblk.rlen, initblk.tlen);
-#endif
- } else {
- struct pcnet_initblk16 initblk;
- PCNET_INIT();
-#ifdef PCNET_DEBUG
- printf("initblk.rlen=0x%02x, initblk.tlen=0x%02x\n",
- initblk.rlen, initblk.tlen);
-#endif
- }
-
-#undef PCNET_INIT
-
- CSR_RCVRC(s) = CSR_RCVRL(s);
- CSR_XMTRC(s) = CSR_XMTRL(s);
-
- /* flush any cached receive descriptors */
- s->crmd.rmd1.own = 0;
- s->nrmd.rmd1.own = 0;
- s->nnrmd.rmd1.own = 0;
-
-#ifdef PCNET_DEBUG
- printf("pcnet ss32=%d rdra=0x%08x[%d] tdra=0x%08x[%d]\n",
- BCR_SSIZE32(s),
- s->rdra, CSR_RCVRL(s), s->tdra, CSR_XMTRL(s));
-#endif
-
- s->csr[0] |= 0x0101;
- s->csr[0] &= ~0x0004; /* clear STOP bit */
-}
-
-static void pcnet_start(PCNetState *s)
-{
-#ifdef PCNET_DEBUG
- printf("pcnet_start\n");
-#endif
-
- if (!CSR_DTX(s))
- s->csr[0] |= 0x0010; /* set TXON */
-
- if (!CSR_DRX(s))
- s->csr[0] |= 0x0020; /* set RXON */
-
- /* flush any cached receive descriptors */
- s->crmd.rmd1.own = 0;
- s->nrmd.rmd1.own = 0;
- s->nnrmd.rmd1.own = 0;
-
- s->csr[0] &= ~0x0004; /* clear STOP bit */
- s->csr[0] |= 0x0002;
-}
-
-static void pcnet_stop(PCNetState *s)
-{
-#ifdef PCNET_DEBUG
- printf("pcnet_stop\n");
-#endif
- s->csr[0] &= ~0x7feb;
- s->csr[0] |= 0x0014;
- s->csr[4] &= ~0x02c2;
- s->csr[5] &= ~0x0011;
- pcnet_poll_timer(s);
-}
-
-static void pcnet_rdte_poll(PCNetState *s)
-{
- s->csr[28] = s->csr[29] = 0;
- if (s->rdra) {
- int bad = 0;
- target_phys_addr_t crda = pcnet_rdra_addr(s, CSR_RCVRC(s));
- target_phys_addr_t nrda = pcnet_rdra_addr(s, -1 + CSR_RCVRC(s));
- target_phys_addr_t nnrd = pcnet_rdra_addr(s, -2 + CSR_RCVRC(s));
-
- if (!s->crmd.rmd1.own) {
- CHECK_RMD(&(s->crmd),PHYSADDR(s,crda), bad);
- }
- if (!bad) {
- if (s->crmd.rmd1.own && !s->nrmd.rmd1.own) {
- CHECK_RMD(&(s->nrmd),PHYSADDR(s,nrda), bad);
- }
- if (bad || (nrda == crda)) nrda = 0;
- if (s->crmd.rmd1.own && s->nrmd.rmd1.own && !s->nnrmd.rmd1.own) {
- CHECK_RMD(&(s->nnrmd),PHYSADDR(s,nnrd), bad);
- }
- if (bad || (nnrd == crda)) nnrd = 0;
-
- s->csr[28] = crda & 0xffff;
- s->csr[29] = crda >> 16;
- s->csr[26] = nrda & 0xffff;
- s->csr[27] = nrda >> 16;
- s->csr[36] = nnrd & 0xffff;
- s->csr[37] = nnrd >> 16;
-#ifdef PCNET_DEBUG
- if (bad) {
- printf("pcnet: BAD RMD RECORDS AFTER 0x%08x\n",
- PHYSADDR(s,crda));
- }
- } else {
- printf("pcnet: BAD RMD RDA=0x%08x\n", PHYSADDR(s,crda));
-#endif
- }
- }
-
- if (CSR_CRDA(s)) {
- CSR_CRBC(s) = s->crmd.rmd1.bcnt;
- CSR_CRST(s) = ((uint32_t *)&(s->crmd))[1] >> 16;
-#ifdef PCNET_DEBUG_RMD_X
- printf("CRDA=0x%08x CRST=0x%04x RCVRC=%d RMD1=0x%08x RMD2=0x%08x\n",
- PHYSADDR(s,CSR_CRDA(s)), CSR_CRST(s), CSR_RCVRC(s),
- ((uint32_t *)&(s->crmd))[1], ((uint32_t *)&(s->crmd))[2]);
- PRINT_RMD(&rmd);
-#endif
- } else {
- CSR_CRBC(s) = CSR_CRST(s) = 0;
- }
-
- if (CSR_NRDA(s)) {
- CSR_NRBC(s) = s->nrmd.rmd1.bcnt;
- CSR_NRST(s) = ((uint32_t *)&(s->nrmd))[1] >> 16;
- } else {
- CSR_NRBC(s) = CSR_NRST(s) = 0;
- }
-
-}
-
-static int pcnet_tdte_poll(PCNetState *s)
-{
- s->csr[34] = s->csr[35] = 0;
- if (s->tdra) {
- target_phys_addr_t cxda = s->tdra +
- (CSR_XMTRL(s) - CSR_XMTRC(s)) *
- (BCR_SWSTYLE(s) ? 16 : 8 );
- int bad = 0;
- s->csr[0] &= ~0x0008; /* clear TDMD */
- CHECK_TMD(PHYSADDR(s, cxda),bad);
- if (!bad) {
- if (CSR_CXDA(s) != cxda) {
- s->csr[60] = s->csr[34];
- s->csr[61] = s->csr[35];
- s->csr[62] = CSR_CXBC(s);
- s->csr[63] = CSR_CXST(s);
- }
- s->csr[34] = cxda & 0xffff;
- s->csr[35] = cxda >> 16;
-#ifdef PCNET_DEBUG
- } else {
- printf("pcnet: BAD TMD XDA=0x%08x\n", PHYSADDR(s,cxda));
-#endif
- }
- }
-
- if (CSR_CXDA(s)) {
- CSR_CXBC(s) = s->tmd.tmd1.bcnt;
- CSR_CXST(s) = ((uint32_t *)&(s->tmd))[1] >> 16;
- } else {
- CSR_CXBC(s) = CSR_CXST(s) = 0;
- }
-
- return !!(CSR_CXST(s) & 0x8000);
-}
-
-static int pcnet_can_receive(void *opaque)
-{
- PCNetState *s = opaque;
- if (CSR_STOP(s) || CSR_SPND(s))
- return 0;
-
- pcnet_rdte_poll(s);
- if (!(CSR_CRST(s) & 0x8000)) {
- return 0;
- }
- return sizeof(s->rx_buffer)-16;
-}
-
-#define MIN_BUF_SIZE 60
-
-static void pcnet_receive(void *opaque, const uint8_t *buf, int size)
-{
- PCNetState *s = opaque;
- int is_padr = 0, is_bcast = 0, is_ladr = 0;
- int pad;
-
- if (CSR_DRX(s) || CSR_STOP(s) || CSR_SPND(s) || !size)
- return;
-
-#ifdef PCNET_DEBUG
- printf("pcnet_receive size=%d\n", size);
-#endif
-
- /* if too small buffer, then expand it */
- if (size < MIN_BUF_SIZE)
- pad = MIN_BUF_SIZE - size + 4;
- else
- pad = 4;
-
- if (CSR_PROM(s)
- || (is_padr=padr_match(s, buf, size))
- || (is_bcast=padr_bcast(s, buf, size))
- || (is_ladr=ladr_match(s, buf, size))) {
-
- pcnet_rdte_poll(s);
-
- if (size > 2000) {
-#ifdef PCNET_DEBUG_RMD
- printf("pcnet - oversize packet discarded.\n");
-#endif
- } else if (!(CSR_CRST(s) & 0x8000)) {
-#ifdef PCNET_DEBUG_RMD
- printf("pcnet - no buffer: RCVRC=%d\n", CSR_RCVRC(s));
-#endif
- s->csr[0] |= 0x1000; /* Set MISS flag */
- CSR_MISSC(s)++;
- } else {
- uint8_t *src = &s->rx_buffer[8];
- target_phys_addr_t crda = CSR_CRDA(s);
- target_phys_addr_t nrda = CSR_NRDA(s);
- target_phys_addr_t nnrda = CSR_NNRD(s);
- int pktcount = 0;
- int packet_size = size + pad;
-
- memcpy(src, buf, size);
- memset(src + size, 0, pad);
- size += pad;
-
-#ifdef PCNET_DEBUG_MATCH
- PRINT_PKTHDR(buf);
-#endif
-
- s->crmd.rmd1.stp = 1;
- do {
- int count = MIN(4096 - s->crmd.rmd1.bcnt,size);
- target_phys_addr_t rbadr = PHYSADDR(s, s->crmd.rmd0.rbadr);
- cpu_physical_memory_write(rbadr, src, count);
- cpu_physical_memory_set_dirty(rbadr);
- cpu_physical_memory_set_dirty(rbadr+count);
- src += count; size -= count;
- if (size > 0 && s->nrmd.rmd1.own) {
- RMDSTORE(&(s->crmd), PHYSADDR(s,crda));
- crda = nrda;
- nrda = nnrda;
- s->crmd = s->nrmd;
- s->nrmd = s->nnrmd;
- s->nnrmd.rmd1.own = 0;
- }
- pktcount++;
- } while (size > 0 && s->crmd.rmd1.own);
-
- if (size == 0) {
- s->crmd.rmd1.enp = 1;
- s->crmd.rmd2.mcnt = packet_size;
- s->crmd.rmd1.pam = !CSR_PROM(s) && is_padr;
- s->crmd.rmd1.lafm = !CSR_PROM(s) && is_ladr;
- s->crmd.rmd1.bam = !CSR_PROM(s) && is_bcast;
- } else {
- s->crmd.rmd1.oflo = 1;
- s->crmd.rmd1.buff = 1;
- s->crmd.rmd1.err = 1;
- }
- RMDSTORE(&(s->crmd), PHYSADDR(s,crda));
- s->csr[0] |= 0x0400;
- s->crmd = s->nrmd;
- s->nrmd = s->nnrmd;
- s->nnrmd.rmd1.own = 0;
-
-#ifdef PCNET_DEBUG
- printf("RCVRC=%d CRDA=0x%08x BLKS=%d\n",
- CSR_RCVRC(s), PHYSADDR(s,CSR_CRDA(s)), pktcount);
-#endif
-#ifdef PCNET_DEBUG_RMD
- PRINT_RMD(&s->crmd);
-#endif
-
- while (pktcount--) {
- if (CSR_RCVRC(s) <= 1)
- CSR_RCVRC(s) = CSR_RCVRL(s);
- else
- CSR_RCVRC(s)--;
- }
-
- pcnet_rdte_poll(s);
-
- }
- }
-
- pcnet_poll(s);
- pcnet_update_irq(s);
-}
-
-static void pcnet_transmit(PCNetState *s)
-{
- target_phys_addr_t start_addr = 0;
- struct pcnet_TMD start_tmd;
- int count = CSR_XMTRL(s)-1;
- int xmit_pos = 0;
- int len;
-
-
- if (!CSR_TXON(s)) {
- s->csr[0] &= ~0x0008;
- return;
- }
-
- while (pcnet_tdte_poll(s)) {
-
-#ifdef PCNET_DEBUG_TMD
- printf(" TMDLOAD 0x%08x\n", PHYSADDR(s,CSR_CXDA(s)));
- PRINT_TMD(&(s->tmd));
-#endif
- len = 4096 - s->tmd.tmd1.bcnt;
- if (CSR_XMTRC(s) <= 1)
- CSR_XMTRC(s) = CSR_XMTRL(s);
- else
- CSR_XMTRC(s)--;
-
- /* handle start followed by start */
- if (s->tmd.tmd1.stp && start_addr) {
- TMDSTORE(&start_tmd, start_addr);
- start_addr = 0;
- xmit_pos = 0;
- }
- if ((xmit_pos + len) < sizeof(s->tx_buffer)) {
- cpu_physical_memory_read(PHYSADDR(s, s->tmd.tmd0.tbadr),
- s->tx_buffer + xmit_pos, len);
- xmit_pos += len;
- } else {
- s->tmd.tmd2.buff = s->tmd.tmd2.uflo = s->tmd.tmd1.err = 1;
- TMDSTORE(&(s->tmd), PHYSADDR(s,CSR_CXDA(s)));
- if (start_addr == PHYSADDR(s,CSR_CXDA(s)))
- start_addr = 0; /* don't clear own bit twice */
- continue;
- }
- if (s->tmd.tmd1.stp) {
- if (s->tmd.tmd1.enp) {
- if (CSR_LOOP(s))
- pcnet_receive(s, s->tx_buffer, xmit_pos);
- else
- qemu_send_packet(s->nd, s->tx_buffer, xmit_pos);
-
- s->csr[4] |= 0x0008; /* set TXSTRT */
- TMDSTORE(&(s->tmd), PHYSADDR(s,CSR_CXDA(s)));
- xmit_pos = 0;
- count--;
- } else {
- start_tmd = s->tmd;
- start_addr = PHYSADDR(s,CSR_CXDA(s));
- }
- } else if (s->tmd.tmd1.enp) {
- TMDSTORE(&(s->tmd), PHYSADDR(s,CSR_CXDA(s)));
- if (start_addr) {
- TMDSTORE(&start_tmd, start_addr);
- }
- start_addr = 0;
- xmit_pos = 0;
- count--;
-
- } else {
- TMDSTORE(&(s->tmd), PHYSADDR(s,CSR_CXDA(s)));
- }
- if (!CSR_TOKINTD(s) || (CSR_LTINTEN(s) && s->tmd.tmd1.ltint))
- s->csr[0] |= 0x0200; /* set TINT */
-
- if (count <= 0)
- break;
-
- }
- if (start_addr) {
- start_tmd.tmd2.buff = start_tmd.tmd2.uflo = start_tmd.tmd1.err = 1;
- TMDSTORE(&start_tmd, PHYSADDR(s,start_addr));
- s->csr[0] |= 0x0200; /* set TINT */
- if (!CSR_DXSUFLO(s)) {
- s->csr[0] &= ~0x0010;
- }
- }
-}
-
-static void pcnet_poll(PCNetState *s)
-{
- if (CSR_RXON(s)) {
- pcnet_rdte_poll(s);
- }
-
- if (CSR_TDMD(s) ||
- (CSR_TXON(s) && !CSR_DPOLL(s) && pcnet_tdte_poll(s)))
- pcnet_transmit(s);
-}
-
-static void pcnet_poll_timer(void *opaque)
-{
- PCNetState *s = opaque;
-
- if (CSR_TDMD(s)) {
- pcnet_transmit(s);
- }
-
- pcnet_update_irq(s);
-
- if (!CSR_STOP(s) && !CSR_SPND(s) && !CSR_DPOLL(s)) {
- uint64_t now = qemu_get_clock(vm_clock) * 33;
- if (!s->timer || !now)
- s->timer = now;
- else {
- uint64_t t = now - s->timer + CSR_POLL(s);
- if (t > 0xffffLL) {
- pcnet_poll(s);
- CSR_POLL(s) = CSR_PINT(s);
- } else
- CSR_POLL(s) = t;
- }
- }
-}
-
-
-static void pcnet_csr_writew(PCNetState *s, uint32_t rap, uint32_t new_value)
-{
- uint16_t val = new_value;
-#ifdef PCNET_DEBUG_CSR
- printf("pcnet_csr_writew rap=%d val=0x%04x\n", rap, val);
-#endif
- switch (rap) {
- case 0:
- s->csr[0] &= ~(val & 0x7f00); /* Clear any interrupt flags */
-
- s->csr[0] = (s->csr[0] & ~0x0040) | (val & 0x0048);
-
- val = (val & 0x007f) | (s->csr[0] & 0x7f00);
-
- /* IFF STOP, STRT and INIT are set, clear STRT and INIT */
- if ((val&7) == 7)
- val &= ~3;
-
- if (!CSR_STOP(s) && (val & 4))
- pcnet_stop(s);
-
- if (!CSR_INIT(s) && (val & 1))
- pcnet_init(s);
-
- if (!CSR_STRT(s) && (val & 2))
- pcnet_start(s);
-
- if (CSR_TDMD(s))
- pcnet_transmit(s);
-
- return;
- case 1:
- case 2:
- case 8:
- case 9:
- case 10:
- case 11:
- case 12:
- case 13:
- case 14:
- case 15:
- case 18: /* CRBAL */
- case 19: /* CRBAU */
- case 20: /* CXBAL */
- case 21: /* CXBAU */
- case 22: /* NRBAU */
- case 23: /* NRBAU */
- case 24:
- case 25:
- case 26:
- case 27:
- case 28:
- case 29:
- case 30:
- case 31:
- case 32:
- case 33:
- case 34:
- case 35:
- case 36:
- case 37:
- case 38:
- case 39:
- case 40: /* CRBC */
- case 41:
- case 42: /* CXBC */
- case 43:
- case 44:
- case 45:
- case 46: /* POLL */
- case 47: /* POLLINT */
- case 72:
- case 74:
- case 76: /* RCVRL */
- case 78: /* XMTRL */
- case 112:
- if (CSR_STOP(s) || CSR_SPND(s))
- break;
- return;
- case 3:
- break;
- case 4:
- s->csr[4] &= ~(val & 0x026a);
- val &= ~0x026a; val |= s->csr[4] & 0x026a;
- break;
- case 5:
- s->csr[5] &= ~(val & 0x0a90);
- val &= ~0x0a90; val |= s->csr[5] & 0x0a90;
- break;
- case 16:
- pcnet_csr_writew(s,1,val);
- return;
- case 17:
- pcnet_csr_writew(s,2,val);
- return;
- case 58:
- pcnet_bcr_writew(s,BCR_SWS,val);
- break;
- default:
- return;
- }
- s->csr[rap] = val;
-}
-
-static uint32_t pcnet_csr_readw(PCNetState *s, uint32_t rap)
-{
- uint32_t val;
- switch (rap) {
- case 0:
- pcnet_update_irq(s);
- val = s->csr[0];
- val |= (val & 0x7800) ? 0x8000 : 0;
- break;
- case 16:
- return pcnet_csr_readw(s,1);
- case 17:
- return pcnet_csr_readw(s,2);
- case 58:
- return pcnet_bcr_readw(s,BCR_SWS);
- case 88:
- val = s->csr[89];
- val <<= 16;
- val |= s->csr[88];
- break;
- default:
- val = s->csr[rap];
- }
-#ifdef PCNET_DEBUG_CSR
- printf("pcnet_csr_readw rap=%d val=0x%04x\n", rap, val);
-#endif
- return val;
-}
-
-static void pcnet_bcr_writew(PCNetState *s, uint32_t rap, uint32_t val)
-{
- rap &= 127;
-#ifdef PCNET_DEBUG_BCR
- printf("pcnet_bcr_writew rap=%d val=0x%04x\n", rap, val);
-#endif
- switch (rap) {
- case BCR_SWS:
- if (!(CSR_STOP(s) || CSR_SPND(s)))
- return;
- val &= ~0x0300;
- switch (val & 0x00ff) {
- case 0:
- val |= 0x0200;
- break;
- case 1:
- val |= 0x0100;
- break;
- case 2:
- case 3:
- val |= 0x0300;
- break;
- default:
- printf("Bad SWSTYLE=0x%02x\n", val & 0xff);
- val = 0x0200;
- break;
- }
-#ifdef PCNET_DEBUG
- printf("BCR_SWS=0x%04x\n", val);
-#endif
- case BCR_LNKST:
- case BCR_LED1:
- case BCR_LED2:
- case BCR_LED3:
- case BCR_MC:
- case BCR_FDC:
- case BCR_BSBC:
- case BCR_EECAS:
- case BCR_PLAT:
- s->bcr[rap] = val;
- break;
- default:
- break;
- }
-}
-
-static uint32_t pcnet_bcr_readw(PCNetState *s, uint32_t rap)
-{
- uint32_t val;
- rap &= 127;
- switch (rap) {
- case BCR_LNKST:
- case BCR_LED1:
- case BCR_LED2:
- case BCR_LED3:
- val = s->bcr[rap] & ~0x8000;
- val |= (val & 0x017f & s->lnkst) ? 0x8000 : 0;
- break;
- default:
- val = rap < 32 ? s->bcr[rap] : 0;
- break;
- }
-#ifdef PCNET_DEBUG_BCR
- printf("pcnet_bcr_readw rap=%d val=0x%04x\n", rap, val);
-#endif
- return val;
-}
-
-static void pcnet_h_reset(PCNetState *s)
-{
- int i;
- uint16_t checksum;
-
- /* Initialize the PROM */
-
- memcpy(s->prom, s->nd->macaddr, 6);
- s->prom[12] = s->prom[13] = 0x00;
- s->prom[14] = s->prom[15] = 0x57;
-
- for (i = 0,checksum = 0; i < 16; i++)
- checksum += s->prom[i];
- *(uint16_t *)&s->prom[12] = cpu_to_le16(checksum);
-
-
- s->bcr[BCR_MSRDA] = 0x0005;
- s->bcr[BCR_MSWRA] = 0x0005;
- s->bcr[BCR_MC ] = 0x0002;
- s->bcr[BCR_LNKST] = 0x00c0;
- s->bcr[BCR_LED1 ] = 0x0084;
- s->bcr[BCR_LED2 ] = 0x0088;
- s->bcr[BCR_LED3 ] = 0x0090;
- s->bcr[BCR_FDC ] = 0x0000;
- s->bcr[BCR_BSBC ] = 0x9001;
- s->bcr[BCR_EECAS] = 0x0002;
- s->bcr[BCR_SWS ] = 0x0200;
- s->bcr[BCR_PLAT ] = 0xff06;
-
- pcnet_s_reset(s);
-}
-
-static void pcnet_aprom_writeb(void *opaque, uint32_t addr, uint32_t val)
-{
- PCNetState *s = opaque;
-#ifdef PCNET_DEBUG
- printf("pcnet_aprom_writeb addr=0x%08x val=0x%02x\n", addr, val);
-#endif
- /* Check APROMWE bit to enable write access */
- if (pcnet_bcr_readw(s,2) & 0x80)
- s->prom[addr & 15] = val;
-}
-
-static uint32_t pcnet_aprom_readb(void *opaque, uint32_t addr)
-{
- PCNetState *s = opaque;
- uint32_t val = s->prom[addr &= 15];
-#ifdef PCNET_DEBUG
- printf("pcnet_aprom_readb addr=0x%08x val=0x%02x\n", addr, val);
-#endif
- return val;
-}
-
-static void pcnet_ioport_writew(void *opaque, uint32_t addr, uint32_t val)
-{
- PCNetState *s = opaque;
- pcnet_poll_timer(s);
-#ifdef PCNET_DEBUG_IO
- printf("pcnet_ioport_writew addr=0x%08x val=0x%04x\n", addr, val);
-#endif
- if (!BCR_DWIO(s)) {
- switch (addr & 0x0f) {
- case 0x00: /* RDP */
- pcnet_csr_writew(s, s->rap, val);
- break;
- case 0x02:
- s->rap = val & 0x7f;
- break;
- case 0x06:
- pcnet_bcr_writew(s, s->rap, val);
- break;
- }
- }
- pcnet_update_irq(s);
- update_select_wakeup_events();
-}
-
-static uint32_t pcnet_ioport_readw(void *opaque, uint32_t addr)
-{
- PCNetState *s = opaque;
- uint32_t val = -1;
- pcnet_poll_timer(s);
- if (!BCR_DWIO(s)) {
- switch (addr & 0x0f) {
- case 0x00: /* RDP */
- val = pcnet_csr_readw(s, s->rap);
- break;
- case 0x02:
- val = s->rap;
- break;
- case 0x04:
- pcnet_s_reset(s);
- val = 0;
- break;
- case 0x06:
- val = pcnet_bcr_readw(s, s->rap);
- break;
- }
- }
- pcnet_update_irq(s);
- update_select_wakeup_events();
-#ifdef PCNET_DEBUG_IO
- printf("pcnet_ioport_readw addr=0x%08x val=0x%04x\n", addr, val & 0xffff);
-#endif
- return val;
-}
-
-static void pcnet_ioport_writel(void *opaque, uint32_t addr, uint32_t val)
-{
- PCNetState *s = opaque;
- pcnet_poll_timer(s);
-#ifdef PCNET_DEBUG_IO
- printf("pcnet_ioport_writel addr=0x%08x val=0x%08x\n", addr, val);
-#endif
- if (BCR_DWIO(s)) {
- switch (addr & 0x0f) {
- case 0x00: /* RDP */
- pcnet_csr_writew(s, s->rap, val & 0xffff);
- break;
- case 0x04:
- s->rap = val & 0x7f;
- break;
- case 0x0c:
- pcnet_bcr_writew(s, s->rap, val & 0xffff);
- break;
- }
- } else
- if ((addr & 0x0f) == 0) {
- /* switch device to dword i/o mode */
- pcnet_bcr_writew(s, BCR_BSBC, pcnet_bcr_readw(s, BCR_BSBC) | 0x0080);
-#ifdef PCNET_DEBUG_IO
- printf("device switched into dword i/o mode\n");
-#endif
- }
- pcnet_update_irq(s);
- update_select_wakeup_events();
-}
-
-static uint32_t pcnet_ioport_readl(void *opaque, uint32_t addr)
-{
- PCNetState *s = opaque;
- uint32_t val = -1;
- pcnet_poll_timer(s);
- if (BCR_DWIO(s)) {
- switch (addr & 0x0f) {
- case 0x00: /* RDP */
- val = pcnet_csr_readw(s, s->rap);
- break;
- case 0x04:
- val = s->rap;
- break;
- case 0x08:
- pcnet_s_reset(s);
- val = 0;
- break;
- case 0x0c:
- val = pcnet_bcr_readw(s, s->rap);
- break;
- }
- }
- pcnet_update_irq(s);
- update_select_wakeup_events();
-#ifdef PCNET_DEBUG_IO
- printf("pcnet_ioport_readl addr=0x%08x val=0x%08x\n", addr, val);
-#endif
- return val;
-}
-
-static void pcnet_ioport_map(PCIDevice *pci_dev, int region_num,
- uint32_t addr, uint32_t size, int type)
-{
- PCNetState *d = (PCNetState *)pci_dev;
-
-#ifdef PCNET_DEBUG_IO
- printf("pcnet_ioport_map addr=0x%04x size=0x%04x\n", addr, size);
-#endif
-
- register_ioport_write(addr, 16, 1, pcnet_aprom_writeb, d);
- register_ioport_read(addr, 16, 1, pcnet_aprom_readb, d);
-
- register_ioport_write(addr + 0x10, 0x10, 2, pcnet_ioport_writew, d);
- register_ioport_read(addr + 0x10, 0x10, 2, pcnet_ioport_readw, d);
- register_ioport_write(addr + 0x10, 0x10, 4, pcnet_ioport_writel, d);
- register_ioport_read(addr + 0x10, 0x10, 4, pcnet_ioport_readl, d);
-}
-
-static void pcnet_mmio_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
- PCNetState *d = opaque;
-#ifdef PCNET_DEBUG_IO
- printf("pcnet_mmio_writeb addr=0x%08x val=0x%02x\n", addr, val);
-#endif
- if (!(addr & 0x10))
- pcnet_aprom_writeb(d, addr & 0x0f, val);
-}
-
-static uint32_t pcnet_mmio_readb(void *opaque, target_phys_addr_t addr)
-{
- PCNetState *d = opaque;
- uint32_t val = -1;
- if (!(addr & 0x10))
- val = pcnet_aprom_readb(d, addr & 0x0f);
-#ifdef PCNET_DEBUG_IO
- printf("pcnet_mmio_readb addr=0x%08x val=0x%02x\n", addr, val & 0xff);
-#endif
- return val;
-}
-
-static void pcnet_mmio_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
- PCNetState *d = opaque;
-#ifdef PCNET_DEBUG_IO
- printf("pcnet_mmio_writew addr=0x%08x val=0x%04x\n", addr, val);
-#endif
- if (addr & 0x10)
- pcnet_ioport_writew(d, addr & 0x0f, val);
- else {
- addr &= 0x0f;
- pcnet_aprom_writeb(d, addr, val & 0xff);
- pcnet_aprom_writeb(d, addr+1, (val & 0xff00) >> 8);
- }
-}
-
-static uint32_t pcnet_mmio_readw(void *opaque, target_phys_addr_t addr)
-{
- PCNetState *d = opaque;
- uint32_t val = -1;
- if (addr & 0x10)
- val = pcnet_ioport_readw(d, addr & 0x0f);
- else {
- addr &= 0x0f;
- val = pcnet_aprom_readb(d, addr+1);
- val <<= 8;
- val |= pcnet_aprom_readb(d, addr);
- }
-#ifdef PCNET_DEBUG_IO
- printf("pcnet_mmio_readw addr=0x%08x val = 0x%04x\n", addr, val & 0xffff);
-#endif
- return val;
-}
-
-static void pcnet_mmio_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
- PCNetState *d = opaque;
-#ifdef PCNET_DEBUG_IO
- printf("pcnet_mmio_writel addr=0x%08x val=0x%08x\n", addr, val);
-#endif
- if (addr & 0x10)
- pcnet_ioport_writel(d, addr & 0x0f, val);
- else {
- addr &= 0x0f;
- pcnet_aprom_writeb(d, addr, val & 0xff);
- pcnet_aprom_writeb(d, addr+1, (val & 0xff00) >> 8);
- pcnet_aprom_writeb(d, addr+2, (val & 0xff0000) >> 16);
- pcnet_aprom_writeb(d, addr+3, (val & 0xff000000) >> 24);
- }
-}
-
-static uint32_t pcnet_mmio_readl(void *opaque, target_phys_addr_t addr)
-{
- PCNetState *d = opaque;
- uint32_t val;
- if (addr & 0x10)
- val = pcnet_ioport_readl(d, addr & 0x0f);
- else {
- addr &= 0x0f;
- val = pcnet_aprom_readb(d, addr+3);
- val <<= 8;
- val |= pcnet_aprom_readb(d, addr+2);
- val <<= 8;
- val |= pcnet_aprom_readb(d, addr+1);
- val <<= 8;
- val |= pcnet_aprom_readb(d, addr);
- }
-#ifdef PCNET_DEBUG_IO
- printf("pcnet_mmio_readl addr=0x%08x val=0x%08x\n", addr, val);
-#endif
- return val;
-}
-
-
-static CPUWriteMemoryFunc *pcnet_mmio_write[] = {
- (CPUWriteMemoryFunc *)&pcnet_mmio_writeb,
- (CPUWriteMemoryFunc *)&pcnet_mmio_writew,
- (CPUWriteMemoryFunc *)&pcnet_mmio_writel
-};
-
-static CPUReadMemoryFunc *pcnet_mmio_read[] = {
- (CPUReadMemoryFunc *)&pcnet_mmio_readb,
- (CPUReadMemoryFunc *)&pcnet_mmio_readw,
- (CPUReadMemoryFunc *)&pcnet_mmio_readl
-};
-
-static void pcnet_mmio_map(PCIDevice *pci_dev, int region_num,
- uint32_t addr, uint32_t size, int type)
-{
- PCNetState *d = (PCNetState *)pci_dev;
-
-#ifdef PCNET_DEBUG_IO
- printf("pcnet_ioport_map addr=0x%08x 0x%08x\n", addr, size);
-#endif
-
- cpu_register_physical_memory(addr, PCNET_PNPMMIO_SIZE, d->mmio_io_addr);
-}
-
-void pci_pcnet_init(PCIBus *bus, NetDriverState *nd)
-{
- PCNetState *d;
- uint8_t *pci_conf;
-
-#if 0
- printf("sizeof(RMD)=%d, sizeof(TMD)=%d\n",
- sizeof(struct pcnet_RMD), sizeof(struct pcnet_TMD));
-#endif
-
- d = (PCNetState *)pci_register_device(bus, "PCNet", sizeof(PCNetState),
- -1, NULL, NULL);
-
- pci_conf = d->dev.config;
-
- *(uint16_t *)&pci_conf[0x00] = cpu_to_le16(0x1022);
- *(uint16_t *)&pci_conf[0x02] = cpu_to_le16(0x2000);
- *(uint16_t *)&pci_conf[0x04] = cpu_to_le16(0x0007);
- *(uint16_t *)&pci_conf[0x06] = cpu_to_le16(0x0280);
- pci_conf[0x08] = 0x10;
- pci_conf[0x09] = 0x00;
- pci_conf[0x0a] = 0x00; // ethernet network controller
- pci_conf[0x0b] = 0x02;
- pci_conf[0x0e] = 0x00; // header_type
-
- *(uint32_t *)&pci_conf[0x10] = cpu_to_le32(0x00000001);
- *(uint32_t *)&pci_conf[0x14] = cpu_to_le32(0x00000000);
-
- pci_conf[0x3d] = 1; // interrupt pin 0
- pci_conf[0x3e] = 0x06;
- pci_conf[0x3f] = 0xff;
-
- /* Handler for memory-mapped I/O */
- d->mmio_io_addr =
- cpu_register_io_memory(0, pcnet_mmio_read, pcnet_mmio_write, d);
-
- pci_register_io_region((PCIDevice *)d, 0, PCNET_IOPORT_SIZE,
- PCI_ADDRESS_SPACE_IO, pcnet_ioport_map);
-
- pci_register_io_region((PCIDevice *)d, 1, PCNET_PNPMMIO_SIZE,
- PCI_ADDRESS_SPACE_MEM, pcnet_mmio_map);
-
- d->nd = nd;
-
- pcnet_h_reset(d);
-
- qemu_add_read_packet(nd, pcnet_can_receive, pcnet_receive, d);
-}
+++ /dev/null
-/*
- * QEMU AMD PC-Net II (Am79C970A) emulation
- *
- * Copyright (c) 2004 Antony T Curtis
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-/* This software was written to be compatible with the specification:
- * AMD Am79C970A PCnet-PCI II Ethernet Controller Data-Sheet
- * AMD Publication# 19436 Rev:E Amendment/0 Issue Date: June 2000
- */
-
-#ifdef __GNUC__
-#define PACKED(A) A __attribute__ ((packed))
-#else
-#error FixMe
-#endif
-
-/* BUS CONFIGURATION REGISTERS */
-#define BCR_MSRDA 0
-#define BCR_MSWRA 1
-#define BCR_MC 2
-#define BCR_LNKST 4
-#define BCR_LED1 5
-#define BCR_LED2 6
-#define BCR_LED3 7
-#define BCR_FDC 9
-#define BCR_BSBC 18
-#define BCR_EECAS 19
-#define BCR_SWS 20
-#define BCR_PLAT 22
-
-#define BCR_DWIO(S) !!((S)->bcr[BCR_BSBC] & 0x0080)
-#define BCR_SSIZE32(S) !!((S)->bcr[BCR_SWS ] & 0x0100)
-#define BCR_SWSTYLE(S) ((S)->bcr[BCR_SWS ] & 0x00FF)
-
-#define CSR_INIT(S) !!(((S)->csr[0])&0x0001)
-#define CSR_STRT(S) !!(((S)->csr[0])&0x0002)
-#define CSR_STOP(S) !!(((S)->csr[0])&0x0004)
-#define CSR_TDMD(S) !!(((S)->csr[0])&0x0008)
-#define CSR_TXON(S) !!(((S)->csr[0])&0x0010)
-#define CSR_RXON(S) !!(((S)->csr[0])&0x0020)
-#define CSR_INEA(S) !!(((S)->csr[0])&0x0040)
-#define CSR_LAPPEN(S) !!(((S)->csr[3])&0x0020)
-#define CSR_DXSUFLO(S) !!(((S)->csr[3])&0x0040)
-#define CSR_ASTRP_RCV(S) !!(((S)->csr[4])&0x0800)
-#define CSR_DPOLL(S) !!(((S)->csr[4])&0x1000)
-#define CSR_SPND(S) !!(((S)->csr[5])&0x0001)
-#define CSR_LTINTEN(S) !!(((S)->csr[5])&0x4000)
-#define CSR_TOKINTD(S) !!(((S)->csr[5])&0x8000)
-#define CSR_DRX(S) !!(((S)->csr[15])&0x0001)
-#define CSR_DTX(S) !!(((S)->csr[15])&0x0002)
-#define CSR_LOOP(S) !!(((S)->csr[15])&0x0004)
-#define CSR_DRCVPA(S) !!(((S)->csr[15])&0x2000)
-#define CSR_DRCVBC(S) !!(((S)->csr[15])&0x4000)
-#define CSR_PROM(S) !!(((S)->csr[15])&0x8000)
-
-#define CSR_CRBC(S) ((S)->csr[40])
-#define CSR_CRST(S) ((S)->csr[41])
-#define CSR_CXBC(S) ((S)->csr[42])
-#define CSR_CXST(S) ((S)->csr[43])
-#define CSR_NRBC(S) ((S)->csr[44])
-#define CSR_NRST(S) ((S)->csr[45])
-#define CSR_POLL(S) ((S)->csr[46])
-#define CSR_PINT(S) ((S)->csr[47])
-#define CSR_RCVRC(S) ((S)->csr[72])
-#define CSR_XMTRC(S) ((S)->csr[74])
-#define CSR_RCVRL(S) ((S)->csr[76])
-#define CSR_XMTRL(S) ((S)->csr[78])
-#define CSR_MISSC(S) ((S)->csr[112])
-
-#define CSR_IADR(S) ((S)->csr[ 1] | ((S)->csr[ 2] << 16))
-#define CSR_CRBA(S) ((S)->csr[18] | ((S)->csr[19] << 16))
-#define CSR_CXBA(S) ((S)->csr[20] | ((S)->csr[21] << 16))
-#define CSR_NRBA(S) ((S)->csr[22] | ((S)->csr[23] << 16))
-#define CSR_BADR(S) ((S)->csr[24] | ((S)->csr[25] << 16))
-#define CSR_NRDA(S) ((S)->csr[26] | ((S)->csr[27] << 16))
-#define CSR_CRDA(S) ((S)->csr[28] | (((uint32_t)((S)->csr[29])) << 16))
-#define CSR_BADX(S) ((S)->csr[30] | ((S)->csr[31] << 16))
-#define CSR_NXDA(S) ((S)->csr[32] | ((S)->csr[33] << 16))
-#define CSR_CXDA(S) ((S)->csr[34] | ((S)->csr[35] << 16))
-#define CSR_NNRD(S) ((S)->csr[36] | ((S)->csr[37] << 16))
-#define CSR_NNXD(S) ((S)->csr[38] | ((S)->csr[39] << 16))
-#define CSR_PXDA(S) ((S)->csr[60] | ((S)->csr[61] << 16))
-#define CSR_NXBA(S) ((S)->csr[64] | ((S)->csr[65] << 16))
-
-#define PHYSADDR(S,A) \
- (BCR_SSIZE32(S) ? (A) : (A) | ((0xff00 & (uint32_t)(S)->csr[2])<<16))
-
-struct pcnet_initblk16 {
- uint16_t mode;
- uint16_t padr1;
- uint16_t padr2;
- uint16_t padr3;
- uint16_t ladrf1;
- uint16_t ladrf2;
- uint16_t ladrf3;
- uint16_t ladrf4;
- unsigned PACKED(rdra:24);
- unsigned PACKED(res1:5);
- unsigned PACKED(rlen:3);
- unsigned PACKED(tdra:24);
- unsigned PACKED(res2:5);
- unsigned PACKED(tlen:3);
-};
-
-struct pcnet_initblk32 {
- uint16_t mode;
- unsigned PACKED(res1:4);
- unsigned PACKED(rlen:4);
- unsigned PACKED(res2:4);
- unsigned PACKED(tlen:4);
- uint16_t padr1;
- uint16_t padr2;
- uint16_t padr3;
- uint16_t _res;
- uint16_t ladrf1;
- uint16_t ladrf2;
- uint16_t ladrf3;
- uint16_t ladrf4;
- uint32_t rdra;
- uint32_t tdra;
-};
-
-struct pcnet_TMD {
- struct {
- unsigned tbadr:32;
- } tmd0;
- struct {
- unsigned PACKED(bcnt:12), PACKED(ones:4), PACKED(res:7), PACKED(bpe:1);
- unsigned PACKED(enp:1), PACKED(stp:1), PACKED(def:1), PACKED(one:1);
- unsigned PACKED(ltint:1), PACKED(nofcs:1), PACKED(err:1), PACKED(own:1);
- } tmd1;
- struct {
- unsigned PACKED(trc:4), PACKED(res:12);
- unsigned PACKED(tdr:10), PACKED(rtry:1), PACKED(lcar:1);
- unsigned PACKED(lcol:1), PACKED(exdef:1), PACKED(uflo:1), PACKED(buff:1);
- } tmd2;
- struct {
- unsigned res:32;
- } tmd3;
-};
-
-struct pcnet_RMD {
- struct {
- unsigned rbadr:32;
- } rmd0;
- struct {
- unsigned PACKED(bcnt:12), PACKED(ones:4), PACKED(res:4);
- unsigned PACKED(bam:1), PACKED(lafm:1), PACKED(pam:1), PACKED(bpe:1);
- unsigned PACKED(enp:1), PACKED(stp:1), PACKED(buff:1), PACKED(crc:1);
- unsigned PACKED(oflo:1), PACKED(fram:1), PACKED(err:1), PACKED(own:1);
- } rmd1;
- struct {
- unsigned PACKED(mcnt:12), PACKED(zeros:4);
- unsigned PACKED(rpc:8), PACKED(rcc:8);
- } rmd2;
- struct {
- unsigned res:32;
- } rmd3;
-};
-
-typedef struct PCNetState_st PCNetState;
-
-struct PCNetState_st {
- PCIDevice dev;
- NetDriverState *nd;
- int mmio_io_addr, rap, isr, lnkst;
- target_phys_addr_t rdra, tdra;
- uint8_t prom[16];
- uint16_t csr[128];
- uint16_t bcr[32];
- uint64_t timer;
- int recv_pos;
- uint8_t tx_buffer[2048];
- uint8_t rx_buffer[2048];
- struct pcnet_TMD tmd;
- struct pcnet_RMD crmd;
- struct pcnet_RMD nrmd;
- struct pcnet_RMD nnrmd;
-};
-
-
-#define PRINT_TMD(T) printf( \
- "TMD0 : TBADR=0x%08x\n" \
- "TMD1 : OWN=%d, ERR=%d, FCS=%d, LTI=%d, " \
- "ONE=%d, DEF=%d, STP=%d, ENP=%d,\n" \
- " BPE=%d, BCNT=%d\n" \
- "TMD2 : BUF=%d, UFL=%d, EXD=%d, LCO=%d, " \
- "LCA=%d, RTR=%d,\n" \
- " TDR=%d, TRC=%d\n", \
- (T)->tmd0.tbadr, \
- (T)->tmd1.own, (T)->tmd1.err, (T)->tmd1.nofcs, \
- (T)->tmd1.ltint, (T)->tmd1.one, (T)->tmd1.def, \
- (T)->tmd1.stp, (T)->tmd1.enp, (T)->tmd1.bpe, \
- 4096-(T)->tmd1.bcnt, \
- (T)->tmd2.buff, (T)->tmd2.uflo, (T)->tmd2.exdef,\
- (T)->tmd2.lcol, (T)->tmd2.lcar, (T)->tmd2.rtry, \
- (T)->tmd2.tdr, (T)->tmd2.trc)
-
-#define PRINT_RMD(R) printf( \
- "RMD0 : RBADR=0x%08x\n" \
- "RMD1 : OWN=%d, ERR=%d, FRAM=%d, OFLO=%d, " \
- "CRC=%d, BUFF=%d, STP=%d, ENP=%d,\n " \
- "BPE=%d, PAM=%d, LAFM=%d, BAM=%d, ONES=%d, BCNT=%d\n" \
- "RMD2 : RCC=%d, RPC=%d, MCNT=%d, ZEROS=%d\n", \
- (R)->rmd0.rbadr, \
- (R)->rmd1.own, (R)->rmd1.err, (R)->rmd1.fram, \
- (R)->rmd1.oflo, (R)->rmd1.crc, (R)->rmd1.buff, \
- (R)->rmd1.stp, (R)->rmd1.enp, (R)->rmd1.bpe, \
- (R)->rmd1.pam, (R)->rmd1.lafm, (R)->rmd1.bam, \
- (R)->rmd1.ones, 4096-(R)->rmd1.bcnt, \
- (R)->rmd2.rcc, (R)->rmd2.rpc, (R)->rmd2.mcnt, \
- (R)->rmd2.zeros)
-
-static inline void pcnet_tmd_load(PCNetState *s, struct pcnet_TMD *tmd, target_phys_addr_t addr)
-{
- if (!BCR_SWSTYLE(s)) {
- uint16_t xda[4];
- cpu_physical_memory_read(addr,
- (void *)&xda[0], sizeof(xda));
- ((uint32_t *)tmd)[0] = (xda[0]&0xffff) |
- ((xda[1]&0x00ff) << 16);
- ((uint32_t *)tmd)[1] = (xda[2]&0xffff)|
- ((xda[1] & 0xff00) << 16);
- ((uint32_t *)tmd)[2] =
- (xda[3] & 0xffff) << 16;
- ((uint32_t *)tmd)[3] = 0;
- }
- else
- if (BCR_SWSTYLE(s) != 3) {
- ((uint32_t *)tmd)[2] = 0;
- cpu_physical_memory_read(addr+4, (void *)&tmd->tmd1, 4);
- cpu_physical_memory_read(addr, (void *)&tmd->tmd0, 4);
- } else {
- uint32_t xda[2];
- cpu_physical_memory_read(addr+4, (void *)&xda[0], sizeof(xda));
- ((uint32_t *)tmd)[0] = xda[1];
- ((uint32_t *)tmd)[1] = xda[0];
- ((uint32_t *)tmd)[2] = 0;
- }
-}
-
-static inline void pcnet_tmd_store(PCNetState *s, struct pcnet_TMD *tmd, target_phys_addr_t addr)
-{
- tmd->tmd1.own = 0;
- cpu_physical_memory_set_dirty(addr);
- if (!BCR_SWSTYLE(s)) {
- uint16_t xda[4];
- xda[0] = ((uint32_t *)tmd)[0] & 0xffff;
- xda[1] = ((((uint32_t *)tmd)[0]>>16)&0x00ff) |
- ((((uint32_t *)tmd)[1]>>16)&0xff00);
- xda[2] = ((uint32_t *)tmd)[1] & 0xffff;
- xda[3] = ((uint32_t *)tmd)[2] >> 16;
- cpu_physical_memory_write(addr,
- (void *)&xda[0], sizeof(xda));
- cpu_physical_memory_set_dirty(addr+7);
- }
- else {
- if (BCR_SWSTYLE(s) != 3) {
- cpu_physical_memory_write(addr+8, (void *)&tmd->tmd2, 4);
- cpu_physical_memory_write(addr+4, (void *)&tmd->tmd1, 4);
- } else {
- uint32_t xda[2];
- xda[0] = ((uint32_t *)tmd)[2];
- xda[1] = ((uint32_t *)tmd)[1];
- cpu_physical_memory_write(addr, (void *)&xda[0], sizeof(xda));
- }
- cpu_physical_memory_set_dirty(addr+15);
- }
-}
-
-static inline void pcnet_rmd_load(PCNetState *s, struct pcnet_RMD *rmd, target_phys_addr_t addr)
-{
- if (!BCR_SWSTYLE(s)) {
- uint16_t rda[4];
- cpu_physical_memory_read(addr,
- (void *)&rda[0], sizeof(rda));
- ((uint32_t *)rmd)[0] = (rda[0]&0xffff)|
- ((rda[1] & 0x00ff) << 16);
- ((uint32_t *)rmd)[1] = (rda[2]&0xffff)|
- ((rda[1] & 0xff00) << 16);
- ((uint32_t *)rmd)[2] = rda[3] & 0xffff;
- ((uint32_t *)rmd)[3] = 0;
- }
- else
- if (BCR_SWSTYLE(s) != 3) {
- ((uint32_t *)rmd)[2] = 0;
- cpu_physical_memory_read(addr+4, (void *)&rmd->rmd1, 4);
- cpu_physical_memory_read(addr, (void *)&rmd->rmd0, 4);
- } else {
- uint32_t rda[2];
- cpu_physical_memory_read(addr+4, (void *)&rda[0], sizeof(rda));
- ((uint32_t *)rmd)[0] = rda[1];
- ((uint32_t *)rmd)[1] = rda[0];
- ((uint32_t *)rmd)[2] = 0;
- }
-}
-
-static inline void pcnet_rmd_store(PCNetState *s, struct pcnet_RMD *rmd, target_phys_addr_t addr)
-{
- rmd->rmd1.own = 0;
- cpu_physical_memory_set_dirty(addr);
- if (!BCR_SWSTYLE(s)) {
- uint16_t rda[4]; \
- rda[0] = ((uint32_t *)rmd)[0] & 0xffff; \
- rda[1] = ((((uint32_t *)rmd)[0]>>16)&0xff)|\
- ((((uint32_t *)rmd)[1]>>16)&0xff00);\
- rda[2] = ((uint32_t *)rmd)[1] & 0xffff; \
- rda[3] = ((uint32_t *)rmd)[2] & 0xffff; \
- cpu_physical_memory_write(addr, \
- (void *)&rda[0], sizeof(rda)); \
- cpu_physical_memory_set_dirty(addr+7);
- }
- else {
- if (BCR_SWSTYLE(s) != 3) {
- cpu_physical_memory_write(addr+8, (void *)&rmd->rmd2, 4);
- cpu_physical_memory_write(addr+4, (void *)&rmd->rmd1, 4);
- } else {
- uint32_t rda[2];
- rda[0] = ((uint32_t *)rmd)[2];
- rda[1] = ((uint32_t *)rmd)[1];
- cpu_physical_memory_write(addr, (void *)&rda[0], sizeof(rda));
- }
- cpu_physical_memory_set_dirty(addr+15);
- }
-}
-
-
-#define TMDLOAD(TMD,ADDR) pcnet_tmd_load(s,TMD,ADDR)
-
-#define TMDSTORE(TMD,ADDR) pcnet_tmd_store(s,TMD,ADDR)
-
-#define RMDLOAD(RMD,ADDR) pcnet_rmd_load(s,RMD,ADDR)
-
-#define RMDSTORE(RMD,ADDR) pcnet_rmd_store(s,RMD,ADDR)
-
-#define CHECK_RMD(RMD,ADDR,RES) do { \
- RMDLOAD((RMD),(ADDR)); \
- (RES) |= ((RMD)->rmd1.ones != 15); \
-} while (0)
-
-#define CHECK_TMD(ADDR,RES) do { \
- TMDLOAD(&(s->tmd),(ADDR)); \
- (RES) |= (s->tmd.tmd1.ones != 15); \
-} while (0)
-
-
-#define PRINT_PKTHDR(BUF) do { \
- struct ether_header *hdr = (void *)(BUF); \
- printf("packet dhost=%02x:%02x:%02x:%02x:%02x:%02x, " \
- "shost=%02x:%02x:%02x:%02x:%02x:%02x, " \
- "type=0x%04x (bcast=%d)\n", \
- hdr->ether_dhost[0],hdr->ether_dhost[1],hdr->ether_dhost[2], \
- hdr->ether_dhost[3],hdr->ether_dhost[4],hdr->ether_dhost[5], \
- hdr->ether_shost[0],hdr->ether_shost[1],hdr->ether_shost[2], \
- hdr->ether_shost[3],hdr->ether_shost[4],hdr->ether_shost[5], \
- htons(hdr->ether_type), \
- !!ETHER_IS_MULTICAST(hdr->ether_dhost)); \
-} while (0)
-
-#define MULTICAST_FILTER_LEN 8
-
-static inline uint32_t lnc_mchash(const uint8_t *ether_addr)
-{
-#define LNC_POLYNOMIAL 0xEDB88320UL
- uint32_t crc = 0xFFFFFFFF;
- int idx, bit;
- uint8_t data;
-
- for (idx = 0; idx < ETHER_ADDR_LEN; idx++) {
- for (data = *ether_addr++, bit = 0; bit < MULTICAST_FILTER_LEN; bit++) {
- crc = (crc >> 1) ^ (((crc ^ data) & 1) ? LNC_POLYNOMIAL : 0);
- data >>= 1;
- }
- }
- return crc;
-#undef LNC_POLYNOMIAL
-}
-
-#define MIN(X,Y) ((X>Y) ? (Y) : (X))
-
-#define CRC(crc, ch) (crc = (crc >> 8) ^ crctab[(crc ^ (ch)) & 0xff])
-
-/* generated using the AUTODIN II polynomial
- * x^32 + x^26 + x^23 + x^22 + x^16 +
- * x^12 + x^11 + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x^1 + 1
- */
-static const uint32_t crctab[256] = {
- 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
- 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
- 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
- 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
- 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
- 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
- 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
- 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
- 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
- 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
- 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,
- 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
- 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,
- 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
- 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
- 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
- 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,
- 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
- 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
- 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
- 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
- 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
- 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,
- 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
- 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
- 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
- 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
- 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
- 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
- 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
- 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,
- 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
- 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
- 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
- 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
- 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
- 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,
- 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
- 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
- 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
- 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,
- 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
- 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,
- 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
- 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
- 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
- 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,
- 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
- 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
- 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
- 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
- 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
- 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,
- 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
- 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
- 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
- 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
- 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
- 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
- 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
- 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,
- 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
- 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
- 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d,
-};
-
-static inline int padr_match(PCNetState *s, const uint8_t *buf, int size)
-{
- struct ether_header *hdr = (void *)buf;
- uint8_t padr[6] = {
- s->csr[12] & 0xff, s->csr[12] >> 8,
- s->csr[13] & 0xff, s->csr[13] >> 8,
- s->csr[14] & 0xff, s->csr[14] >> 8
- };
- int result = (!CSR_DRCVPA(s)) && !bcmp(hdr->ether_dhost, padr, 6);
-#ifdef PCNET_DEBUG_MATCH
- printf("packet dhost=%02x:%02x:%02x:%02x:%02x:%02x, "
- "padr=%02x:%02x:%02x:%02x:%02x:%02x\n",
- hdr->ether_dhost[0],hdr->ether_dhost[1],hdr->ether_dhost[2],
- hdr->ether_dhost[3],hdr->ether_dhost[4],hdr->ether_dhost[5],
- padr[0],padr[1],padr[2],padr[3],padr[4],padr[5]);
- printf("padr_match result=%d\n", result);
-#endif
- return result;
-}
-
-static inline int padr_bcast(PCNetState *s, const uint8_t *buf, int size)
-{
- static uint8_t BCAST[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
- struct ether_header *hdr = (void *)buf;
- int result = !CSR_DRCVBC(s) && !bcmp(hdr->ether_dhost, BCAST, 6);
-#ifdef PCNET_DEBUG_MATCH
- printf("padr_bcast result=%d\n", result);
-#endif
- return result;
-}
-
-static inline int ladr_match(PCNetState *s, const uint8_t *buf, int size)
-{
- struct ether_header *hdr = (void *)buf;
- if ((*(hdr->ether_dhost)&0x01) &&
- ((uint64_t *)&s->csr[8])[0] != 0LL) {
- uint8_t ladr[8] = {
- s->csr[8] & 0xff, s->csr[8] >> 8,
- s->csr[9] & 0xff, s->csr[9] >> 8,
- s->csr[10] & 0xff, s->csr[10] >> 8,
- s->csr[11] & 0xff, s->csr[11] >> 8
- };
- int index = lnc_mchash(hdr->ether_dhost) >> 26;
- return !!(ladr[index >> 3] & (1 << (index & 7)));
- }
- return 0;
-}
-
-static inline target_phys_addr_t pcnet_rdra_addr(PCNetState *s, int idx)
-{
- while (idx < 1) idx += CSR_RCVRL(s);
- return s->rdra + ((CSR_RCVRL(s) - idx) * (BCR_SWSTYLE(s) ? 16 : 8));
-}
-
-static inline int64_t pcnet_get_next_poll_time(PCNetState *s, int64_t current_time)
-{
- int64_t next_time = current_time +
- muldiv64(65536 - (CSR_SPND(s) ? 0 : CSR_POLL(s)),
- ticks_per_sec, 33000000L);
- if (next_time <= current_time)
- next_time = current_time + 1;
- return next_time;
-}
-
-
+++ /dev/null
-/*
- * PIIX4 ACPI controller emulation
- *
- * Winston liwen Wang, winston.l.wang@intel.com
- * Copyright (c) 2006 , Intel Corporation.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include "vl.h"
-#define FREQUENCE_PMTIMER 3753425
-/* acpi register bit define here */
-
-/* PM1_STS */
-#define TMROF_STS (1 << 0)
-#define BM_STS (1 << 4)
-#define GBL_STS (1 << 5)
-#define PWRBTN_STS (1 << 8)
-#define RTC_STS (1 << 10)
-#define PRBTNOR_STS (1 << 11)
-#define WAK_STS (1 << 15)
-/* PM1_EN */
-#define TMROF_EN (1 << 0)
-#define GBL_EN (1 << 5)
-#define PWRBTN_EN (1 << 8)
-#define RTC_EN (1 << 10)
-/* PM1_CNT */
-#define SCI_EN (1 << 0)
-#define GBL_RLS (1 << 2)
-#define SLP_EN (1 << 13)
-
-/* Bits of PM1a register define here */
-#define SLP_TYP_MASK 0x1C00
-#define SLP_VAL 0x1C00
-
-typedef struct AcpiDeviceState AcpiDeviceState;
-AcpiDeviceState *acpi_device_table;
-
-/* Bits of PM1a register define here */
-typedef struct PMTState {
- uint32_t count;
- int irq;
- uint64_t next_pm_time;
- QEMUTimer *pm_timer;
-}PMTState;
-
-typedef struct PM1Event_BLK {
- uint16_t pm1_status; /* pm1a_EVT_BLK */
- uint16_t pm1_enable; /* pm1a_EVT_BLK+2 */
-}PM1Event_BLK;
-
-typedef struct PCIAcpiState {
- PCIDevice dev;
- uint16_t irq;
- uint16_t pm1_status; /* pm1a_EVT_BLK */
- uint16_t pm1_enable; /* pm1a_EVT_BLK+2 */
- uint16_t pm1_control; /* pm1a_ECNT_BLK */
- uint32_t pm1_timer; /* pmtmr_BLK */
-} PCIAcpiState;
-
-static PMTState *pmtimer_state;
-static PCIAcpiState *acpi_state;
-
-static void pmtimer_save(QEMUFile *f, void *opaque)
-{
- PMTState *s = opaque;
-
- qemu_put_be32s(f, &s->count);
- qemu_put_be32s(f, &s->irq);
- qemu_put_be64s(f, &s->next_pm_time);
- qemu_put_timer(f, s->pm_timer);
-}
-
-static int pmtimer_load(QEMUFile *f, void *opaque, int version_id)
-{
- PMTState *s = opaque;
-
- if (version_id != 1)
- return -EINVAL;
- qemu_get_be32s(f, &s->count);
- qemu_get_be32s(f, &s->irq);
- qemu_get_be64s(f, &s->next_pm_time);
- qemu_get_timer(f, s->pm_timer);
- return 0;
-
-}
-
-static inline void acpi_set_irq(PCIAcpiState *s)
-{
-/* no real SCI event need for now, so comment the following line out */
-/* pic_set_irq(s->irq, 1); */
- printf("acpi_set_irq: s->irq %x \n",s->irq);
-}
-
-static void pm_timer_update(void *opaque)
-{
- PMTState *s = opaque;
- s->next_pm_time += muldiv64(1, ticks_per_sec,FREQUENCE_PMTIMER);
- qemu_mod_timer(s->pm_timer, s->next_pm_time);
- acpi_state->pm1_timer ++;
-
- /* If pm timer is zero then reset it to zero. */
- if (acpi_state->pm1_timer >= 0x1000000) {
-/* printf("pm_timerupdate: timer overflow: %x \n", acpi_state->pm1_timer); */
-
- acpi_state->pm1_timer = 0;
- acpi_state->pm1_status = acpi_state->pm1_status | TMROF_STS;
- /* If TMROF_EN is set then send the irq. */
- if ((acpi_state->pm1_enable & TMROF_EN) == TMROF_EN) {
- acpi_set_irq(acpi_state);
- acpi_state->pm1_enable = 0x00; /* only need one time...*/
- }
- }
- s->count = acpi_state->pm1_timer;
-}
-
-static PMTState *pmtimer_init(void)
-{
- PMTState *s;
-
- s = qemu_mallocz(sizeof(PMTState));
- if (!s)
- return NULL;
-
- /* s->irq = irq; */
-
- s->pm_timer = qemu_new_timer(vm_clock, pm_timer_update, s);
-
- s->count = 0;
- s->next_pm_time = qemu_get_clock(vm_clock) + muldiv64(1, ticks_per_sec,FREQUENCE_PMTIMER) + 1;
- qemu_mod_timer(s->pm_timer, s->next_pm_time);
-
- register_savevm("pm timer", 1, 1, pmtimer_save, pmtimer_load, s);
- return s;
-}
-
-static void acpi_reset(PCIAcpiState *s)
-{
- uint8_t *pci_conf;
- pci_conf = s->dev.config;
-
- pci_conf[0x42] = 0x00;
- pci_conf[0x43] = 0x00;
- s->irq = 9;
- s->pm1_status = 0;
- s->pm1_enable = 0x00; /* TMROF_EN should cleared */
- s->pm1_control = SCI_EN; /* SCI_EN */
- s->pm1_timer = 0;
-}
-
-/*byte access */
-static void acpiPm1Status_writeb(void *opaque, uint32_t addr, uint32_t val)
-{
- PCIAcpiState *s = opaque;
-
- if ((val&TMROF_STS)==TMROF_STS)
- s->pm1_status = s->pm1_status&!TMROF_STS;
-
- if ((val&GBL_STS)==GBL_STS)
- s->pm1_status = s->pm1_status&!GBL_STS;
-
-/* printf("acpiPm1Status_writeb \n addr %x val:%x pm1_status:%x \n", addr, val,s->pm1_status); */
-}
-
-static uint32_t acpiPm1Status_readb(void *opaque, uint32_t addr)
-{
- PCIAcpiState *s = opaque;
- uint32_t val;
-
- val = s->pm1_status;
-/* printf("acpiPm1Status_readb \n addr %x val:%x\n", addr, val); */
-
- return val;
-}
-
-static void acpiPm1StatusP1_writeb(void *opaque, uint32_t addr, uint32_t val)
-{
- PCIAcpiState *s = opaque;
-
- s->pm1_status = (val<<8)||(s->pm1_status);
-/* printf("acpiPm1StatusP1_writeb \n addr %x val:%x\n", addr, val); */
-}
-
-static uint32_t acpiPm1StatusP1_readb(void *opaque, uint32_t addr)
-{
- PCIAcpiState *s = opaque;
- uint32_t val;
-
- val = (s->pm1_status)>>8;
- printf("acpiPm1StatusP1_readb \n addr %x val:%x\n", addr, val);
-
- return val;
-}
-
-static void acpiPm1Enable_writeb(void *opaque, uint32_t addr, uint32_t val)
-{
- PCIAcpiState *s = opaque;
-
- s->pm1_enable = val;
-/* printf("acpiPm1Enable_writeb \n addr %x val:%x\n", addr, val); */
-}
-
-static uint32_t acpiPm1Enable_readb(void *opaque, uint32_t addr)
-{
- PCIAcpiState *s = opaque;
- uint32_t val;
-
- val = (s->pm1_enable)||0x1;
-/* printf("acpiPm1Enable_readb \n addr %x val:%x\n", addr, val); */
-
- return val;
-}
-
-static void acpiPm1EnableP1_writeb(void *opaque, uint32_t addr, uint32_t val)
-{
- PCIAcpiState *s = opaque;
-
- s->pm1_enable = (val<<8)||(s->pm1_enable);
-/* printf("acpiPm1EnableP1_writeb \n addr %x val:%x\n", addr, val); */
-
-}
-
-static uint32_t acpiPm1EnableP1_readb(void *opaque, uint32_t addr)
-{
- PCIAcpiState *s = opaque;
- uint32_t val;
-
- val = (s->pm1_enable)>>8;
-/* printf("acpiPm1EnableP1_readb \n addr %x val:%x\n", addr, val); */
-
- return val;
-}
-
-static void acpiPm1Control_writeb(void *opaque, uint32_t addr, uint32_t val)
-{
- PCIAcpiState *s = opaque;
-
- s->pm1_control = val;
-/* printf("acpiPm1Control_writeb \n addr %x val:%x\n", addr, val); */
-
-}
-
-static uint32_t acpiPm1Control_readb(void *opaque, uint32_t addr)
-{
- PCIAcpiState *s = opaque;
- uint32_t val;
-
- val = s->pm1_control;
-/* printf("acpiPm1Control_readb \n addr %x val:%x\n", addr, val); */
-
- return val;
-}
-
-static void acpiPm1ControlP1_writeb(void *opaque, uint32_t addr, uint32_t val)
-{
- PCIAcpiState *s = opaque;
-
- s->pm1_control = (val<<8)||(s->pm1_control);
-/* printf("acpiPm1ControlP1_writeb \n addr %x val:%x\n", addr, val); */
-
- // Check for power off request
-
- if (((val & SLP_EN) != 0) &&
- ((val & SLP_TYP_MASK) == SLP_VAL)) {
- s->pm1_timer=0x0; //clear ACPI timer
- qemu_system_shutdown_request();
- }
-}
-
-static uint32_t acpiPm1ControlP1_readb(void *opaque, uint32_t addr)
-{
- PCIAcpiState *s = opaque;
- uint32_t val;
-
- val = (s->pm1_control)>>8;
-/* printf("acpiPm1ControlP1_readb \n addr %x val:%x\n", addr, val); */
-
- return val;
-}
-
-
-/* word access */
-
-static void acpiPm1Status_writew(void *opaque, uint32_t addr, uint32_t val)
-{
- PCIAcpiState *s = opaque;
-
- if ((val&TMROF_STS)==TMROF_STS)
- s->pm1_status = s->pm1_status&!TMROF_STS;
-
- if ((val&GBL_STS)==GBL_STS)
- s->pm1_status = s->pm1_status&!GBL_STS;
-
-/* printf("acpiPm1Status_writew \n addr %x val:%x pm1_status:%x \n", addr, val,s->pm1_status); */
-}
-
-static uint32_t acpiPm1Status_readw(void *opaque, uint32_t addr)
-{
- PCIAcpiState *s = opaque;
- uint32_t val;
-
- val = s->pm1_status;
-/* printf("acpiPm1Status_readw \n addr %x val:%x\n", addr, val); */
-
- return val;
-}
-
-static void acpiPm1Enable_writew(void *opaque, uint32_t addr, uint32_t val)
-{
- PCIAcpiState *s = opaque;
-
- s->pm1_enable = val;
-/* printf("acpiPm1Enable_writew \n addr %x val:%x\n", addr, val); */
-
-}
-
-static uint32_t acpiPm1Enable_readw(void *opaque, uint32_t addr)
-{
- PCIAcpiState *s = opaque;
- uint32_t val;
-
- val = s->pm1_enable;
-/* printf("acpiPm1Enable_readw \n addr %x val:%x\n", addr, val); */
-
- return val;
-}
-
-static void acpiPm1Control_writew(void *opaque, uint32_t addr, uint32_t val)
-{
- PCIAcpiState *s = opaque;
-
- s->pm1_control = val;
-/* printf("acpiPm1Control_writew \n addr %x val:%x\n", addr, val); */
-
- // Check for power off request
-
- if (((val & SLP_EN) != 0) &&
- ((val & SLP_TYP_MASK) == SLP_VAL)) {
- qemu_system_shutdown_request();
- }
-
-}
-
-static uint32_t acpiPm1Control_readw(void *opaque, uint32_t addr)
-{
- PCIAcpiState *s = opaque;
- uint32_t val;
-
- val = s->pm1_control;
-/* printf("acpiPm1Control_readw \n addr %x val:%x\n", addr, val); */
-
- return val;
-}
-
-/* dword access */
-
-static void acpiPm1Event_writel(void *opaque, uint32_t addr, uint32_t val)
-{
- PCIAcpiState *s = opaque;
-
- s->pm1_status = val;
- s->pm1_enable = val>>16;
-/* printf("acpiPm1Event_writel \n addr %x val:%x \n", addr, val); */
-
-}
-
-static uint32_t acpiPm1Event_readl(void *opaque, uint32_t addr)
-{
- PCIAcpiState *s = opaque;
- uint32_t val;
-
- val = s->pm1_status|(s->pm1_enable<<16);
-/* printf("acpiPm1Event_readl \n addr %x val:%x\n", addr, val); */
-
- return val;
-}
-
-static void acpiPm1Timer_writel(void *opaque, uint32_t addr, uint32_t val)
-{
- PCIAcpiState *s = opaque;
-
- s->pm1_timer = val;
-/* printf("acpiPm1Timer_writel \n addr %x val:%x\n", addr, val); */
-}
-
-static uint32_t acpiPm1Timer_readl(void *opaque, uint32_t addr)
-{
- PCIAcpiState *s = opaque;
- uint32_t val;
-
- val = s->pm1_timer;
-/* printf("acpiPm1Timer_readl \n addr %x val:%x\n", addr, val); */
- return val;
-}
-
-static void acpi_map(PCIDevice *pci_dev, int region_num,
- uint32_t addr, uint32_t size, int type)
-{
- PCIAcpiState *d = (PCIAcpiState *)pci_dev;
-
- printf("register acpi io\n");
-
- /* Byte access */
- register_ioport_write(addr, 1, 1, acpiPm1Status_writeb, d);
- register_ioport_read(addr, 1, 1, acpiPm1Status_readb, d);
- register_ioport_write(addr+1, 1, 1, acpiPm1StatusP1_writeb, d);
- register_ioport_read(addr+1, 1, 1, acpiPm1StatusP1_readb, d);
-
- register_ioport_write(addr + 2, 1, 1, acpiPm1Enable_writeb, d);
- register_ioport_read(addr + 2, 1, 1, acpiPm1Enable_readb, d);
- register_ioport_write(addr + 2 +1, 1, 1, acpiPm1EnableP1_writeb, d);
- register_ioport_read(addr + 2 +1, 1, 1, acpiPm1EnableP1_readb, d);
-
- register_ioport_write(addr + 4, 1, 1, acpiPm1Control_writeb, d);
- register_ioport_read(addr + 4, 1, 1, acpiPm1Control_readb, d);
- register_ioport_write(addr + 4 + 1, 1, 1, acpiPm1ControlP1_writeb, d);
- register_ioport_read(addr + 4 +1, 1, 1, acpiPm1ControlP1_readb, d);
-
- /* Word access */
- register_ioport_write(addr, 2, 2, acpiPm1Status_writew, d);
- register_ioport_read(addr, 2, 2, acpiPm1Status_readw, d);
-
- register_ioport_write(addr + 2, 2, 2, acpiPm1Enable_writew, d);
- register_ioport_read(addr + 2, 2, 2, acpiPm1Enable_readw, d);
-
- register_ioport_write(addr + 4, 2, 2, acpiPm1Control_writew, d);
- register_ioport_read(addr + 4, 2, 2, acpiPm1Control_readw, d);
-
- /* DWord access */
- register_ioport_write(addr, 4, 4, acpiPm1Event_writel, d);
- register_ioport_read(addr, 4, 4, acpiPm1Event_readl, d);
-
- register_ioport_write(addr + 8, 4, 4, acpiPm1Timer_writel, d);
- register_ioport_read(addr + 8, 4, 4, acpiPm1Timer_readl, d);
-}
-
-/* PIIX4 acpi pci configuration space, func 3 */
-void pci_piix4_acpi_init(PCIBus *bus)
-{
- PCIAcpiState *d;
- uint8_t *pci_conf;
-
- /* register a function 3 of PIIX4 */
- d = (PCIAcpiState *)pci_register_device(
- bus, "PIIX4 ACPI", sizeof(PCIAcpiState),
- ((PCIDevice *)piix3_state)->devfn + 3, NULL, NULL);
-
- acpi_state = d;
- pci_conf = d->dev.config;
- pci_conf[0x00] = 0x86; /* Intel */
- pci_conf[0x01] = 0x80;
- pci_conf[0x02] = 0x13;
- pci_conf[0x03] = 0x71;
- pci_conf[0x08] = 0x01; /* B0 stepping */
- pci_conf[0x09] = 0x00; /* base class */
- pci_conf[0x0a] = 0x80; /* Sub class */
- pci_conf[0x0b] = 0x06;
- pci_conf[0x0e] = 0x00;
- pci_conf[0x3d] = 0x01; /* Hardwired to PIRQA is used */
-
- pci_register_io_region((PCIDevice *)d, 4, 0x10,
- PCI_ADDRESS_SPACE_IO, acpi_map);
- /*pmtimer_state = pmtimer_init();*/
- acpi_reset (d);
-}
+++ /dev/null
-/*
- * QEMU Port 0xe9 hack
- *
- * Copyright (c) 2000-2004 E. Marty, the bochs team, D. Decotigny
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-#include <stdio.h>
-#include <unistd.h>
-#include <inttypes.h>
-
-#include "vl.h"
-#include "exec-all.h"
-
-static void bochs_e9_write(void *opaque, uint32_t address, uint32_t data)
-{
- fputc(data, logfile);
-}
-
-static uint32_t bochs_e9_read(void *opaque, uint32_t address)
-{
- return 0xE9;
-}
-
-void port_e9_init ()
-{
- register_ioport_write(0xe9, 1, 1, bochs_e9_write, NULL);
- register_ioport_read (0xe9, 1, 1, bochs_e9_read, NULL);
-}
-
-
+++ /dev/null
-/*
- * QEMU generic PPC hardware System Emulator
- *
- * Copyright (c) 2003-2004 Jocelyn Mayer
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "vl.h"
-#include "m48t59.h"
-
-/*****************************************************************************/
-/* PPC time base and decrementer emulation */
-//#define DEBUG_TB
-
-struct ppc_tb_t {
- /* Time base management */
- int64_t tb_offset; /* Compensation */
- uint32_t tb_freq; /* TB frequency */
- /* Decrementer management */
- uint64_t decr_next; /* Tick for next decr interrupt */
- struct QEMUTimer *decr_timer;
-};
-
-static inline uint64_t cpu_ppc_get_tb (ppc_tb_t *tb_env)
-{
- /* TB time in tb periods */
- return muldiv64(qemu_get_clock(vm_clock) + tb_env->tb_offset,
- tb_env->tb_freq, ticks_per_sec);
-}
-
-uint32_t cpu_ppc_load_tbl (CPUState *env)
-{
- ppc_tb_t *tb_env = env->tb_env;
- uint64_t tb;
-
- tb = cpu_ppc_get_tb(tb_env);
-#ifdef DEBUG_TB
- {
- static int last_time;
- int now;
- now = time(NULL);
- if (last_time != now) {
- last_time = now;
- printf("%s: tb=0x%016lx %d %08lx\n",
- __func__, tb, now, tb_env->tb_offset);
- }
- }
-#endif
-
- return tb & 0xFFFFFFFF;
-}
-
-uint32_t cpu_ppc_load_tbu (CPUState *env)
-{
- ppc_tb_t *tb_env = env->tb_env;
- uint64_t tb;
-
- tb = cpu_ppc_get_tb(tb_env);
-#ifdef DEBUG_TB
- printf("%s: tb=0x%016lx\n", __func__, tb);
-#endif
- return tb >> 32;
-}
-
-static void cpu_ppc_store_tb (ppc_tb_t *tb_env, uint64_t value)
-{
- tb_env->tb_offset = muldiv64(value, ticks_per_sec, tb_env->tb_freq)
- - qemu_get_clock(vm_clock);
-#ifdef DEBUG_TB
- printf("%s: tb=0x%016lx offset=%08x\n", __func__, value);
-#endif
-}
-
-void cpu_ppc_store_tbu (CPUState *env, uint32_t value)
-{
- ppc_tb_t *tb_env = env->tb_env;
-
- cpu_ppc_store_tb(tb_env,
- ((uint64_t)value << 32) | cpu_ppc_load_tbl(env));
-}
-
-void cpu_ppc_store_tbl (CPUState *env, uint32_t value)
-{
- ppc_tb_t *tb_env = env->tb_env;
-
- cpu_ppc_store_tb(tb_env,
- ((uint64_t)cpu_ppc_load_tbu(env) << 32) | value);
-}
-
-uint32_t cpu_ppc_load_decr (CPUState *env)
-{
- ppc_tb_t *tb_env = env->tb_env;
- uint32_t decr;
-
- decr = muldiv64(tb_env->decr_next - qemu_get_clock(vm_clock),
- tb_env->tb_freq, ticks_per_sec);
-#if defined(DEBUG_TB)
- printf("%s: 0x%08x\n", __func__, decr);
-#endif
-
- return decr;
-}
-
-/* When decrementer expires,
- * all we need to do is generate or queue a CPU exception
- */
-static inline void cpu_ppc_decr_excp (CPUState *env)
-{
- /* Raise it */
-#ifdef DEBUG_TB
- printf("raise decrementer exception\n");
-#endif
- cpu_interrupt(env, CPU_INTERRUPT_TIMER);
-}
-
-static void _cpu_ppc_store_decr (CPUState *env, uint32_t decr,
- uint32_t value, int is_excp)
-{
- ppc_tb_t *tb_env = env->tb_env;
- uint64_t now, next;
-
-#ifdef DEBUG_TB
- printf("%s: 0x%08x => 0x%08x\n", __func__, decr, value);
-#endif
- now = qemu_get_clock(vm_clock);
- next = now + muldiv64(value, ticks_per_sec, tb_env->tb_freq);
- if (is_excp)
- next += tb_env->decr_next - now;
- if (next == now)
- next++;
- tb_env->decr_next = next;
- /* Adjust timer */
- qemu_mod_timer(tb_env->decr_timer, next);
- /* If we set a negative value and the decrementer was positive,
- * raise an exception.
- */
- if ((value & 0x80000000) && !(decr & 0x80000000))
- cpu_ppc_decr_excp(env);
-}
-
-void cpu_ppc_store_decr (CPUState *env, uint32_t value)
-{
- _cpu_ppc_store_decr(env, cpu_ppc_load_decr(env), value, 0);
-}
-
-static void cpu_ppc_decr_cb (void *opaque)
-{
- _cpu_ppc_store_decr(opaque, 0x00000000, 0xFFFFFFFF, 1);
-}
-
-/* Set up (once) timebase frequency (in Hz) */
-ppc_tb_t *cpu_ppc_tb_init (CPUState *env, uint32_t freq)
-{
- ppc_tb_t *tb_env;
-
- tb_env = qemu_mallocz(sizeof(ppc_tb_t));
- if (tb_env == NULL)
- return NULL;
- env->tb_env = tb_env;
- if (tb_env->tb_freq == 0 || 1) {
- tb_env->tb_freq = freq;
- /* Create new timer */
- tb_env->decr_timer =
- qemu_new_timer(vm_clock, &cpu_ppc_decr_cb, env);
- /* There is a bug in 2.4 kernels:
- * if a decrementer exception is pending when it enables msr_ee,
- * it's not ready to handle it...
- */
- _cpu_ppc_store_decr(env, 0xFFFFFFFF, 0xFFFFFFFF, 0);
- }
-
- return tb_env;
-}
-
-#if 0
-/*****************************************************************************/
-/* Handle system reset (for now, just stop emulation) */
-void cpu_ppc_reset (CPUState *env)
-{
- printf("Reset asked... Stop emulation\n");
- abort();
-}
-#endif
-
-static void PPC_io_writeb (void *opaque, target_phys_addr_t addr, uint32_t value)
-{
- cpu_outb(NULL, addr & 0xffff, value);
-}
-
-static uint32_t PPC_io_readb (void *opaque, target_phys_addr_t addr)
-{
- uint32_t ret = cpu_inb(NULL, addr & 0xffff);
- return ret;
-}
-
-static void PPC_io_writew (void *opaque, target_phys_addr_t addr, uint32_t value)
-{
-#ifdef TARGET_WORDS_BIGENDIAN
- value = bswap16(value);
-#endif
- cpu_outw(NULL, addr & 0xffff, value);
-}
-
-static uint32_t PPC_io_readw (void *opaque, target_phys_addr_t addr)
-{
- uint32_t ret = cpu_inw(NULL, addr & 0xffff);
-#ifdef TARGET_WORDS_BIGENDIAN
- ret = bswap16(ret);
-#endif
- return ret;
-}
-
-static void PPC_io_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
-{
-#ifdef TARGET_WORDS_BIGENDIAN
- value = bswap32(value);
-#endif
- cpu_outl(NULL, addr & 0xffff, value);
-}
-
-static uint32_t PPC_io_readl (void *opaque, target_phys_addr_t addr)
-{
- uint32_t ret = cpu_inl(NULL, addr & 0xffff);
-
-#ifdef TARGET_WORDS_BIGENDIAN
- ret = bswap32(ret);
-#endif
- return ret;
-}
-
-CPUWriteMemoryFunc *PPC_io_write[] = {
- &PPC_io_writeb,
- &PPC_io_writew,
- &PPC_io_writel,
-};
-
-CPUReadMemoryFunc *PPC_io_read[] = {
- &PPC_io_readb,
- &PPC_io_readw,
- &PPC_io_readl,
-};
-
-/*****************************************************************************/
-/* Debug port */
-void PPC_debug_write (void *opaque, uint32_t addr, uint32_t val)
-{
- addr &= 0xF;
- switch (addr) {
- case 0:
- printf("%c", val);
- break;
- case 1:
- printf("\n");
- fflush(stdout);
- break;
- case 2:
- printf("Set loglevel to %04x\n", val);
- cpu_set_log(val | 0x100);
- break;
- }
-}
-
-/*****************************************************************************/
-/* NVRAM helpers */
-void NVRAM_set_byte (m48t59_t *nvram, uint32_t addr, uint8_t value)
-{
- m48t59_set_addr(nvram, addr);
- m48t59_write(nvram, value);
-}
-
-uint8_t NVRAM_get_byte (m48t59_t *nvram, uint32_t addr)
-{
- m48t59_set_addr(nvram, addr);
- return m48t59_read(nvram);
-}
-
-void NVRAM_set_word (m48t59_t *nvram, uint32_t addr, uint16_t value)
-{
- m48t59_set_addr(nvram, addr);
- m48t59_write(nvram, value >> 8);
- m48t59_set_addr(nvram, addr + 1);
- m48t59_write(nvram, value & 0xFF);
-}
-
-uint16_t NVRAM_get_word (m48t59_t *nvram, uint32_t addr)
-{
- uint16_t tmp;
-
- m48t59_set_addr(nvram, addr);
- tmp = m48t59_read(nvram) << 8;
- m48t59_set_addr(nvram, addr + 1);
- tmp |= m48t59_read(nvram);
-
- return tmp;
-}
-
-void NVRAM_set_lword (m48t59_t *nvram, uint32_t addr, uint32_t value)
-{
- m48t59_set_addr(nvram, addr);
- m48t59_write(nvram, value >> 24);
- m48t59_set_addr(nvram, addr + 1);
- m48t59_write(nvram, (value >> 16) & 0xFF);
- m48t59_set_addr(nvram, addr + 2);
- m48t59_write(nvram, (value >> 8) & 0xFF);
- m48t59_set_addr(nvram, addr + 3);
- m48t59_write(nvram, value & 0xFF);
-}
-
-uint32_t NVRAM_get_lword (m48t59_t *nvram, uint32_t addr)
-{
- uint32_t tmp;
-
- m48t59_set_addr(nvram, addr);
- tmp = m48t59_read(nvram) << 24;
- m48t59_set_addr(nvram, addr + 1);
- tmp |= m48t59_read(nvram) << 16;
- m48t59_set_addr(nvram, addr + 2);
- tmp |= m48t59_read(nvram) << 8;
- m48t59_set_addr(nvram, addr + 3);
- tmp |= m48t59_read(nvram);
-
- return tmp;
-}
-
-void NVRAM_set_string (m48t59_t *nvram, uint32_t addr,
- const unsigned char *str, uint32_t max)
-{
- int i;
-
- for (i = 0; i < max && str[i] != '\0'; i++) {
- m48t59_set_addr(nvram, addr + i);
- m48t59_write(nvram, str[i]);
- }
- m48t59_set_addr(nvram, addr + max - 1);
- m48t59_write(nvram, '\0');
-}
-
-int NVRAM_get_string (m48t59_t *nvram, uint8_t *dst, uint16_t addr, int max)
-{
- int i;
-
- memset(dst, 0, max);
- for (i = 0; i < max; i++) {
- dst[i] = NVRAM_get_byte(nvram, addr + i);
- if (dst[i] == '\0')
- break;
- }
-
- return i;
-}
-
-static uint16_t NVRAM_crc_update (uint16_t prev, uint16_t value)
-{
- uint16_t tmp;
- uint16_t pd, pd1, pd2;
-
- tmp = prev >> 8;
- pd = prev ^ value;
- pd1 = pd & 0x000F;
- pd2 = ((pd >> 4) & 0x000F) ^ pd1;
- tmp ^= (pd1 << 3) | (pd1 << 8);
- tmp ^= pd2 | (pd2 << 7) | (pd2 << 12);
-
- return tmp;
-}
-
-uint16_t NVRAM_compute_crc (m48t59_t *nvram, uint32_t start, uint32_t count)
-{
- uint32_t i;
- uint16_t crc = 0xFFFF;
- int odd;
-
- odd = count & 1;
- count &= ~1;
- for (i = 0; i != count; i++) {
- crc = NVRAM_crc_update(crc, NVRAM_get_word(nvram, start + i));
- }
- if (odd) {
- crc = NVRAM_crc_update(crc, NVRAM_get_byte(nvram, start + i) << 8);
- }
-
- return crc;
-}
-
-#define CMDLINE_ADDR 0x017ff000
-
-int PPC_NVRAM_set_params (m48t59_t *nvram, uint16_t NVRAM_size,
- const unsigned char *arch,
- uint32_t RAM_size, int boot_device,
- uint32_t kernel_image, uint32_t kernel_size,
- const char *cmdline,
- uint32_t initrd_image, uint32_t initrd_size,
- uint32_t NVRAM_image,
- int width, int height, int depth)
-{
- uint16_t crc;
-
- /* Set parameters for Open Hack'Ware BIOS */
- NVRAM_set_string(nvram, 0x00, "QEMU_BIOS", 16);
- NVRAM_set_lword(nvram, 0x10, 0x00000002); /* structure v2 */
- NVRAM_set_word(nvram, 0x14, NVRAM_size);
- NVRAM_set_string(nvram, 0x20, arch, 16);
- NVRAM_set_lword(nvram, 0x30, RAM_size);
- NVRAM_set_byte(nvram, 0x34, boot_device);
- NVRAM_set_lword(nvram, 0x38, kernel_image);
- NVRAM_set_lword(nvram, 0x3C, kernel_size);
- if (cmdline) {
- /* XXX: put the cmdline in NVRAM too ? */
- strcpy(phys_ram_base + CMDLINE_ADDR, cmdline);
- NVRAM_set_lword(nvram, 0x40, CMDLINE_ADDR);
- NVRAM_set_lword(nvram, 0x44, strlen(cmdline));
- } else {
- NVRAM_set_lword(nvram, 0x40, 0);
- NVRAM_set_lword(nvram, 0x44, 0);
- }
- NVRAM_set_lword(nvram, 0x48, initrd_image);
- NVRAM_set_lword(nvram, 0x4C, initrd_size);
- NVRAM_set_lword(nvram, 0x50, NVRAM_image);
-
- NVRAM_set_word(nvram, 0x54, width);
- NVRAM_set_word(nvram, 0x56, height);
- NVRAM_set_word(nvram, 0x58, depth);
- crc = NVRAM_compute_crc(nvram, 0x00, 0xF8);
- NVRAM_set_word(nvram, 0xFC, crc);
-
- return 0;
- }
-
-/*****************************************************************************/
-void ppc_init (int ram_size, int vga_ram_size, int boot_device,
- DisplayState *ds, const char **fd_filename, int snapshot,
- const char *kernel_filename, const char *kernel_cmdline,
- const char *initrd_filename)
-{
- if (prep_enabled) {
- ppc_prep_init(ram_size, vga_ram_size, boot_device, ds, fd_filename,
- snapshot, kernel_filename, kernel_cmdline,
- initrd_filename);
- } else {
- ppc_chrp_init(ram_size, vga_ram_size, boot_device, ds, fd_filename,
- snapshot, kernel_filename, kernel_cmdline,
- initrd_filename);
- }
- /* Special port to get debug messages from Open-Firmware */
- register_ioport_write(0x0F00, 4, 1, &PPC_debug_write, NULL);
-}
+++ /dev/null
-/*
- * QEMU PPC CHRP/PMAC hardware System Emulator
- *
- * Copyright (c) 2004 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "vl.h"
-
-#define BIOS_FILENAME "ppc_rom.bin"
-#define NVRAM_SIZE 0x2000
-
-#define KERNEL_LOAD_ADDR 0x01000000
-#define INITRD_LOAD_ADDR 0x01800000
-
-/* MacIO devices (mapped inside the MacIO address space): CUDA, DBDMA,
- NVRAM (not implemented). */
-
-static int dbdma_mem_index;
-static int cuda_mem_index;
-static int ide0_mem_index;
-static int ide1_mem_index;
-static int openpic_mem_index;
-
-/* DBDMA: currently no op - should suffice right now */
-
-static void dbdma_writeb (void *opaque, target_phys_addr_t addr, uint32_t value)
-{
- printf("%s: 0x%08x <= 0x%08x\n", __func__, addr, value);
-}
-
-static void dbdma_writew (void *opaque, target_phys_addr_t addr, uint32_t value)
-{
-}
-
-static void dbdma_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
-{
-}
-
-static uint32_t dbdma_readb (void *opaque, target_phys_addr_t addr)
-{
- printf("%s: 0x%08x => 0x00000000\n", __func__, addr);
- return 0;
-}
-
-static uint32_t dbdma_readw (void *opaque, target_phys_addr_t addr)
-{
- return 0;
-}
-
-static uint32_t dbdma_readl (void *opaque, target_phys_addr_t addr)
-{
- return 0;
-}
-
-static CPUWriteMemoryFunc *dbdma_write[] = {
- &dbdma_writeb,
- &dbdma_writew,
- &dbdma_writel,
-};
-
-static CPUReadMemoryFunc *dbdma_read[] = {
- &dbdma_readb,
- &dbdma_readw,
- &dbdma_readl,
-};
-
-static void macio_map(PCIDevice *pci_dev, int region_num,
- uint32_t addr, uint32_t size, int type)
-{
- cpu_register_physical_memory(addr + 0x08000, 0x1000, dbdma_mem_index);
- cpu_register_physical_memory(addr + 0x16000, 0x2000, cuda_mem_index);
- cpu_register_physical_memory(addr + 0x1f000, 0x1000, ide0_mem_index);
- cpu_register_physical_memory(addr + 0x20000, 0x1000, ide1_mem_index);
- cpu_register_physical_memory(addr + 0x40000, 0x40000, openpic_mem_index);
-}
-
-static void macio_init(PCIBus *bus)
-{
- PCIDevice *d;
-
- d = pci_register_device(bus, "macio", sizeof(PCIDevice),
- -1, NULL, NULL);
- /* Note: this code is strongly inspirated from the corresponding code
- in PearPC */
- d->config[0x00] = 0x6b; // vendor_id
- d->config[0x01] = 0x10;
- d->config[0x02] = 0x22;
- d->config[0x03] = 0x00;
-
- d->config[0x0a] = 0x00; // class_sub = pci2pci
- d->config[0x0b] = 0xff; // class_base = bridge
- d->config[0x0e] = 0x00; // header_type
-
- d->config[0x3d] = 0x01; // interrupt on pin 1
-
- dbdma_mem_index = cpu_register_io_memory(0, dbdma_read, dbdma_write, NULL);
-
- pci_register_io_region(d, 0, 0x80000,
- PCI_ADDRESS_SPACE_MEM, macio_map);
-}
-
-/* PowerPC PREP hardware initialisation */
-void ppc_chrp_init(int ram_size, int vga_ram_size, int boot_device,
- DisplayState *ds, const char **fd_filename, int snapshot,
- const char *kernel_filename, const char *kernel_cmdline,
- const char *initrd_filename)
-{
- char buf[1024];
- openpic_t *openpic;
- m48t59_t *nvram;
- int PPC_io_memory;
- int ret, linux_boot, i;
- unsigned long bios_offset;
- uint32_t kernel_base, kernel_size, initrd_base, initrd_size;
- PCIBus *pci_bus;
-
- linux_boot = (kernel_filename != NULL);
-
- /* allocate RAM */
- cpu_register_physical_memory(0, ram_size, IO_MEM_RAM);
-
- /* allocate and load BIOS */
- bios_offset = ram_size + vga_ram_size;
- snprintf(buf, sizeof(buf), "%s/%s", bios_dir, BIOS_FILENAME);
- ret = load_image(buf, phys_ram_base + bios_offset);
- if (ret != BIOS_SIZE) {
- fprintf(stderr, "qemu: could not load PPC PREP bios '%s'\n", buf);
- exit(1);
- }
- cpu_register_physical_memory((uint32_t)(-BIOS_SIZE),
- BIOS_SIZE, bios_offset | IO_MEM_ROM);
- cpu_single_env->nip = 0xfffffffc;
-
- if (linux_boot) {
- kernel_base = KERNEL_LOAD_ADDR;
- /* now we can load the kernel */
- kernel_size = load_image(kernel_filename, phys_ram_base + kernel_base);
- if (kernel_size < 0) {
- fprintf(stderr, "qemu: could not load kernel '%s'\n",
- kernel_filename);
- exit(1);
- }
- /* load initrd */
- if (initrd_filename) {
- initrd_base = INITRD_LOAD_ADDR;
- initrd_size = load_image(initrd_filename,
- phys_ram_base + initrd_base);
- if (initrd_size < 0) {
- fprintf(stderr, "qemu: could not load initial ram disk '%s'\n",
- initrd_filename);
- exit(1);
- }
- } else {
- initrd_base = 0;
- initrd_size = 0;
- }
- boot_device = 'm';
- } else {
- kernel_base = 0;
- kernel_size = 0;
- initrd_base = 0;
- initrd_size = 0;
- }
- /* Register CPU as a 74x/75x */
- cpu_ppc_register(cpu_single_env, 0x00080000);
- /* Set time-base frequency to 100 Mhz */
- cpu_ppc_tb_init(cpu_single_env, 100UL * 1000UL * 1000UL);
-
- isa_mem_base = 0x80000000;
- pci_bus = pci_pmac_init();
-
- /* Register 8 MB of ISA IO space */
- PPC_io_memory = cpu_register_io_memory(0, PPC_io_read, PPC_io_write, NULL);
- cpu_register_physical_memory(0xF2000000, 0x00800000, PPC_io_memory);
-
- /* init basic PC hardware */
- vga_initialize(pci_bus, ds, phys_ram_base + ram_size, ram_size,
- vga_ram_size);
- openpic = openpic_init(NULL, &openpic_mem_index, 1);
- pci_pmac_set_openpic(pci_bus, openpic);
-
- /* XXX: suppress that */
- pic_init();
-
- /* XXX: use Mac Serial port */
- serial_init(0x3f8, 4, serial_hds[0]);
-
- for(i = 0; i < nb_nics; i++) {
- pci_ne2000_init(pci_bus, &nd_table[i]);
- }
-
- ide0_mem_index = pmac_ide_init(&bs_table[0], openpic, 0x13);
- ide1_mem_index = pmac_ide_init(&bs_table[2], openpic, 0x13);
-
- /* cuda also initialize ADB */
- cuda_mem_index = cuda_init(openpic, 0x19);
-
- adb_kbd_init(&adb_bus);
- adb_mouse_init(&adb_bus);
-
- macio_init(pci_bus);
-
- nvram = m48t59_init(8, 0xFFF04000, 0x0074, NVRAM_SIZE);
-
- if (graphic_depth != 15 && graphic_depth != 32 && graphic_depth != 8)
- graphic_depth = 15;
-
- PPC_NVRAM_set_params(nvram, NVRAM_SIZE, "CHRP", ram_size, boot_device,
- kernel_base, kernel_size,
- kernel_cmdline,
- initrd_base, initrd_size,
- /* XXX: need an option to load a NVRAM image */
- 0,
- graphic_width, graphic_height, graphic_depth);
- /* No PCI init: the BIOS will do it */
-}
+++ /dev/null
-/*
- * QEMU PPC PREP hardware System Emulator
- *
- * Copyright (c) 2003-2004 Jocelyn Mayer
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "vl.h"
-
-//#define HARD_DEBUG_PPC_IO
-//#define DEBUG_PPC_IO
-
-#define BIOS_FILENAME "ppc_rom.bin"
-#define KERNEL_LOAD_ADDR 0x01000000
-#define INITRD_LOAD_ADDR 0x01800000
-
-extern int loglevel;
-extern FILE *logfile;
-
-#if defined (HARD_DEBUG_PPC_IO) && !defined (DEBUG_PPC_IO)
-#define DEBUG_PPC_IO
-#endif
-
-#if defined (HARD_DEBUG_PPC_IO)
-#define PPC_IO_DPRINTF(fmt, args...) \
-do { \
- if (loglevel & CPU_LOG_IOPORT) { \
- fprintf(logfile, "%s: " fmt, __func__ , ##args); \
- } else { \
- printf("%s : " fmt, __func__ , ##args); \
- } \
-} while (0)
-#elif defined (DEBUG_PPC_IO)
-#define PPC_IO_DPRINTF(fmt, args...) \
-do { \
- if (loglevel & CPU_LOG_IOPORT) { \
- fprintf(logfile, "%s: " fmt, __func__ , ##args); \
- } \
-} while (0)
-#else
-#define PPC_IO_DPRINTF(fmt, args...) do { } while (0)
-#endif
-
-/* Constants for devices init */
-static const int ide_iobase[2] = { 0x1f0, 0x170 };
-static const int ide_iobase2[2] = { 0x3f6, 0x376 };
-static const int ide_irq[2] = { 13, 13 };
-
-#define NE2000_NB_MAX 6
-
-static uint32_t ne2000_io[NE2000_NB_MAX] = { 0x300, 0x320, 0x340, 0x360, 0x280, 0x380 };
-static int ne2000_irq[NE2000_NB_MAX] = { 9, 10, 11, 3, 4, 5 };
-
-//static PITState *pit;
-
-/* ISA IO ports bridge */
-#define PPC_IO_BASE 0x80000000
-
-/* Speaker port 0x61 */
-int speaker_data_on;
-int dummy_refresh_clock;
-
-static void speaker_ioport_write(void *opaque, uint32_t addr, uint32_t val)
-{
-#if 0
- speaker_data_on = (val >> 1) & 1;
- pit_set_gate(pit, 2, val & 1);
-#endif
-}
-
-static uint32_t speaker_ioport_read(void *opaque, uint32_t addr)
-{
-#if 0
- int out;
- out = pit_get_out(pit, 2, qemu_get_clock(vm_clock));
- dummy_refresh_clock ^= 1;
- return (speaker_data_on << 1) | pit_get_gate(pit, 2) | (out << 5) |
- (dummy_refresh_clock << 4);
-#endif
- return 0;
-}
-
-/* PCI intack register */
-/* Read-only register (?) */
-static void _PPC_intack_write (void *opaque, target_phys_addr_t addr, uint32_t value)
-{
- // printf("%s: 0x%08x => 0x%08x\n", __func__, addr, value);
-}
-
-static inline uint32_t _PPC_intack_read (target_phys_addr_t addr)
-{
- uint32_t retval = 0;
-
- if (addr == 0xBFFFFFF0)
- retval = pic_intack_read(NULL);
- // printf("%s: 0x%08x <= %d\n", __func__, addr, retval);
-
- return retval;
-}
-
-static uint32_t PPC_intack_readb (void *opaque, target_phys_addr_t addr)
-{
- return _PPC_intack_read(addr);
-}
-
-static uint32_t PPC_intack_readw (void *opaque, target_phys_addr_t addr)
-{
-#ifdef TARGET_WORDS_BIGENDIAN
- return bswap16(_PPC_intack_read(addr));
-#else
- return _PPC_intack_read(addr);
-#endif
-}
-
-static uint32_t PPC_intack_readl (void *opaque, target_phys_addr_t addr)
-{
-#ifdef TARGET_WORDS_BIGENDIAN
- return bswap32(_PPC_intack_read(addr));
-#else
- return _PPC_intack_read(addr);
-#endif
-}
-
-static CPUWriteMemoryFunc *PPC_intack_write[] = {
- &_PPC_intack_write,
- &_PPC_intack_write,
- &_PPC_intack_write,
-};
-
-static CPUReadMemoryFunc *PPC_intack_read[] = {
- &PPC_intack_readb,
- &PPC_intack_readw,
- &PPC_intack_readl,
-};
-
-/* PowerPC control and status registers */
-#if 0 // Not used
-static struct {
- /* IDs */
- uint32_t veni_devi;
- uint32_t revi;
- /* Control and status */
- uint32_t gcsr;
- uint32_t xcfr;
- uint32_t ct32;
- uint32_t mcsr;
- /* General purpose registers */
- uint32_t gprg[6];
- /* Exceptions */
- uint32_t feen;
- uint32_t fest;
- uint32_t fema;
- uint32_t fecl;
- uint32_t eeen;
- uint32_t eest;
- uint32_t eecl;
- uint32_t eeint;
- uint32_t eemck0;
- uint32_t eemck1;
- /* Error diagnostic */
-} XCSR;
-
-static void PPC_XCSR_writeb (void *opaque, target_phys_addr_t addr, uint32_t value)
-{
- printf("%s: 0x%08lx => 0x%08x\n", __func__, (long)addr, value);
-}
-
-static void PPC_XCSR_writew (void *opaque, target_phys_addr_t addr, uint32_t value)
-{
-#ifdef TARGET_WORDS_BIGENDIAN
- value = bswap16(value);
-#endif
- printf("%s: 0x%08lx => 0x%08x\n", __func__, (long)addr, value);
-}
-
-static void PPC_XCSR_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
-{
-#ifdef TARGET_WORDS_BIGENDIAN
- value = bswap32(value);
-#endif
- printf("%s: 0x%08lx => 0x%08x\n", __func__, (long)addr, value);
-}
-
-static uint32_t PPC_XCSR_readb (void *opaque, target_phys_addr_t addr)
-{
- uint32_t retval = 0;
-
- printf("%s: 0x%08lx <= %d\n", __func__, (long)addr, retval);
-
- return retval;
-}
-
-static uint32_t PPC_XCSR_readw (void *opaque, target_phys_addr_t addr)
-{
- uint32_t retval = 0;
-
- printf("%s: 0x%08lx <= %d\n", __func__, (long)addr, retval);
-#ifdef TARGET_WORDS_BIGENDIAN
- retval = bswap16(retval);
-#endif
-
- return retval;
-}
-
-static uint32_t PPC_XCSR_readl (void *opaque, target_phys_addr_t addr)
-{
- uint32_t retval = 0;
-
- printf("%s: 0x%08lx <= %d\n", __func__, (long)addr, retval);
-#ifdef TARGET_WORDS_BIGENDIAN
- retval = bswap32(retval);
-#endif
-
- return retval;
-}
-
-static CPUWriteMemoryFunc *PPC_XCSR_write[] = {
- &PPC_XCSR_writeb,
- &PPC_XCSR_writew,
- &PPC_XCSR_writel,
-};
-
-static CPUReadMemoryFunc *PPC_XCSR_read[] = {
- &PPC_XCSR_readb,
- &PPC_XCSR_readw,
- &PPC_XCSR_readl,
-};
-#endif
-
-/* Fake super-io ports for PREP platform (Intel 82378ZB) */
-typedef struct sysctrl_t {
- m48t59_t *nvram;
- uint8_t state;
- uint8_t syscontrol;
- uint8_t fake_io[2];
-} sysctrl_t;
-
-enum {
- STATE_HARDFILE = 0x01,
-};
-
-static sysctrl_t *sysctrl;
-
-static void PREP_io_write (void *opaque, uint32_t addr, uint32_t val)
-{
- sysctrl_t *sysctrl = opaque;
-
- PPC_IO_DPRINTF("0x%08lx => 0x%08x\n", (long)addr - PPC_IO_BASE, val);
- sysctrl->fake_io[addr - 0x0398] = val;
-}
-
-static uint32_t PREP_io_read (void *opaque, uint32_t addr)
-{
- sysctrl_t *sysctrl = opaque;
-
- PPC_IO_DPRINTF("0x%08lx <= 0x%08x\n", (long)addr - PPC_IO_BASE,
- sysctrl->fake_io[addr - 0x0398]);
- return sysctrl->fake_io[addr - 0x0398];
-}
-
-static void PREP_io_800_writeb (void *opaque, uint32_t addr, uint32_t val)
-{
- sysctrl_t *sysctrl = opaque;
-
- PPC_IO_DPRINTF("0x%08lx => 0x%08x\n", (long)addr - PPC_IO_BASE, val);
- switch (addr) {
- case 0x0092:
- /* Special port 92 */
- /* Check soft reset asked */
- if (val & 0x01) {
- // cpu_interrupt(cpu_single_env, CPU_INTERRUPT_RESET);
- }
- /* Check LE mode */
- if (val & 0x02) {
- printf("Little Endian mode isn't supported (yet ?)\n");
- abort();
- }
- break;
- case 0x0800:
- /* Motorola CPU configuration register : read-only */
- break;
- case 0x0802:
- /* Motorola base module feature register : read-only */
- break;
- case 0x0803:
- /* Motorola base module status register : read-only */
- break;
- case 0x0808:
- /* Hardfile light register */
- if (val & 1)
- sysctrl->state |= STATE_HARDFILE;
- else
- sysctrl->state &= ~STATE_HARDFILE;
- break;
- case 0x0810:
- /* Password protect 1 register */
- if (sysctrl->nvram != NULL)
- m48t59_toggle_lock(sysctrl->nvram, 1);
- break;
- case 0x0812:
- /* Password protect 2 register */
- if (sysctrl->nvram != NULL)
- m48t59_toggle_lock(sysctrl->nvram, 2);
- break;
- case 0x0814:
- /* L2 invalidate register */
- // tlb_flush(cpu_single_env, 1);
- break;
- case 0x081C:
- /* system control register */
- sysctrl->syscontrol = val & 0x0F;
- break;
- case 0x0850:
- /* I/O map type register */
- if (!(val & 0x01)) {
- printf("No support for non-continuous I/O map mode\n");
- abort();
- }
- break;
- default:
- printf("ERROR: unaffected IO port write: %04lx => %02x\n",
- (long)addr, val);
- break;
- }
-}
-
-static uint32_t PREP_io_800_readb (void *opaque, uint32_t addr)
-{
- sysctrl_t *sysctrl = opaque;
- uint32_t retval = 0xFF;
-
- switch (addr) {
- case 0x0092:
- /* Special port 92 */
- retval = 0x00;
- break;
- case 0x0800:
- /* Motorola CPU configuration register */
- retval = 0xEF; /* MPC750 */
- break;
- case 0x0802:
- /* Motorola Base module feature register */
- retval = 0xAD; /* No ESCC, PMC slot neither ethernet */
- break;
- case 0x0803:
- /* Motorola base module status register */
- retval = 0xE0; /* Standard MPC750 */
- break;
- case 0x080C:
- /* Equipment present register:
- * no L2 cache
- * no upgrade processor
- * no cards in PCI slots
- * SCSI fuse is bad
- */
- retval = 0x3C;
- break;
- case 0x0810:
- /* Motorola base module extended feature register */
- retval = 0x39; /* No USB, CF and PCI bridge. NVRAM present */
- break;
- case 0x0818:
- /* Keylock */
- retval = 0x00;
- break;
- case 0x081C:
- /* system control register
- * 7 - 6 / 1 - 0: L2 cache enable
- */
- retval = sysctrl->syscontrol;
- break;
- case 0x0823:
- /* */
- retval = 0x03; /* no L2 cache */
- break;
- case 0x0850:
- /* I/O map type register */
- retval = 0x01;
- break;
- default:
- printf("ERROR: unaffected IO port: %04lx read\n", (long)addr);
- break;
- }
- PPC_IO_DPRINTF("0x%08lx <= 0x%08x\n", (long)addr - PPC_IO_BASE, retval);
-
- return retval;
-}
-
-extern CPUPPCState *global_env;
-
-#define NVRAM_SIZE 0x2000
-
-/* PowerPC PREP hardware initialisation */
-void ppc_prep_init(int ram_size, int vga_ram_size, int boot_device,
- DisplayState *ds, const char **fd_filename, int snapshot,
- const char *kernel_filename, const char *kernel_cmdline,
- const char *initrd_filename)
-{
- char buf[1024];
- m48t59_t *nvram;
- int PPC_io_memory;
- int ret, linux_boot, i, nb_nics1;
- unsigned long bios_offset;
- uint32_t kernel_base, kernel_size, initrd_base, initrd_size;
- PCIBus *pci_bus;
-
- sysctrl = qemu_mallocz(sizeof(sysctrl_t));
- if (sysctrl == NULL)
- return;
-
- linux_boot = (kernel_filename != NULL);
-
- /* allocate RAM */
- cpu_register_physical_memory(0, ram_size, IO_MEM_RAM);
-
- /* allocate and load BIOS */
- bios_offset = ram_size + vga_ram_size;
- snprintf(buf, sizeof(buf), "%s/%s", bios_dir, BIOS_FILENAME);
- ret = load_image(buf, phys_ram_base + bios_offset);
- if (ret != BIOS_SIZE) {
- fprintf(stderr, "qemu: could not load PPC PREP bios '%s'\n", buf);
- exit(1);
- }
- cpu_register_physical_memory((uint32_t)(-BIOS_SIZE),
- BIOS_SIZE, bios_offset | IO_MEM_ROM);
- cpu_single_env->nip = 0xfffffffc;
-
- if (linux_boot) {
- kernel_base = KERNEL_LOAD_ADDR;
- /* now we can load the kernel */
- kernel_size = load_image(kernel_filename, phys_ram_base + kernel_base);
- if (kernel_size < 0) {
- fprintf(stderr, "qemu: could not load kernel '%s'\n",
- kernel_filename);
- exit(1);
- }
- /* load initrd */
- if (initrd_filename) {
- initrd_base = INITRD_LOAD_ADDR;
- initrd_size = load_image(initrd_filename,
- phys_ram_base + initrd_base);
- if (initrd_size < 0) {
- fprintf(stderr, "qemu: could not load initial ram disk '%s'\n",
- initrd_filename);
- exit(1);
- }
- } else {
- initrd_base = 0;
- initrd_size = 0;
- }
- boot_device = 'm';
- } else {
- kernel_base = 0;
- kernel_size = 0;
- initrd_base = 0;
- initrd_size = 0;
- }
-
- /* Register CPU as a 74x/75x */
- cpu_ppc_register(cpu_single_env, 0x00080000);
- /* Set time-base frequency to 100 Mhz */
- cpu_ppc_tb_init(cpu_single_env, 100UL * 1000UL * 1000UL);
-
- isa_mem_base = 0xc0000000;
- pci_bus = pci_prep_init();
- /* Register 64 KB of ISA IO space */
- PPC_io_memory = cpu_register_io_memory(0, PPC_io_read, PPC_io_write, NULL);
- cpu_register_physical_memory(0x80000000, 0x00010000, PPC_io_memory);
-
- /* init basic PC hardware */
- vga_initialize(pci_bus, ds, phys_ram_base + ram_size, ram_size,
- vga_ram_size);
- rtc_init(0x70, 8);
- // openpic = openpic_init(0x00000000, 0xF0000000, 1);
- // pic_init(openpic);
- pic_init();
- // pit = pit_init(0x40, 0);
-
- serial_init(0x3f8, 4, serial_hds[0]);
- nb_nics1 = nb_nics;
- if (nb_nics1 > NE2000_NB_MAX)
- nb_nics1 = NE2000_NB_MAX;
- for(i = 0; i < nb_nics1; i++) {
- isa_ne2000_init(ne2000_io[i], ne2000_irq[i], &nd_table[i]);
- }
-
- for(i = 0; i < 2; i++) {
- isa_ide_init(ide_iobase[i], ide_iobase2[i], ide_irq[i],
- bs_table[2 * i], bs_table[2 * i + 1]);
- }
- kbd_init();
- DMA_init(1);
- // AUD_init();
- // SB16_init();
-
- fdctrl_init(6, 2, 0, 0x3f0, fd_table);
-
- /* Register speaker port */
- register_ioport_read(0x61, 1, 1, speaker_ioport_read, NULL);
- register_ioport_write(0x61, 1, 1, speaker_ioport_write, NULL);
- /* Register fake IO ports for PREP */
- register_ioport_read(0x398, 2, 1, &PREP_io_read, sysctrl);
- register_ioport_write(0x398, 2, 1, &PREP_io_write, sysctrl);
- /* System control ports */
- register_ioport_read(0x0092, 0x01, 1, &PREP_io_800_readb, sysctrl);
- register_ioport_write(0x0092, 0x01, 1, &PREP_io_800_writeb, sysctrl);
- register_ioport_read(0x0800, 0x52, 1, &PREP_io_800_readb, sysctrl);
- register_ioport_write(0x0800, 0x52, 1, &PREP_io_800_writeb, sysctrl);
- /* PCI intack location */
- PPC_io_memory = cpu_register_io_memory(0, PPC_intack_read,
- PPC_intack_write, NULL);
- cpu_register_physical_memory(0xBFFFFFF0, 0x4, PPC_io_memory);
- /* PowerPC control and status register group */
-#if 0
- PPC_io_memory = cpu_register_io_memory(0, PPC_XCSR_read, PPC_XCSR_write, NULL);
- cpu_register_physical_memory(0xFEFF0000, 0x1000, PPC_io_memory);
-#endif
-
- nvram = m48t59_init(8, 0, 0x0074, NVRAM_SIZE);
- if (nvram == NULL)
- return;
- sysctrl->nvram = nvram;
-
- /* Initialise NVRAM */
- PPC_NVRAM_set_params(nvram, NVRAM_SIZE, "PREP", ram_size, boot_device,
- kernel_base, kernel_size,
- kernel_cmdline,
- initrd_base, initrd_size,
- /* XXX: need an option to load a NVRAM image */
- 0,
- graphic_width, graphic_height, graphic_depth);
-}
+++ /dev/null
-/*
- * QEMU Soundblaster 16 emulation
- *
- * Copyright (c) 2003-2004 Vassili Karpov (malc)
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "vl.h"
-
-#define LENOFA(a) ((int) (sizeof(a)/sizeof(a[0])))
-
-#define dolog(...) AUD_log ("sb16", __VA_ARGS__)
-
-/* #define DEBUG */
-/* #define DEBUG_SB16_MOST */
-
-#ifdef DEBUG
-#define ldebug(...) dolog (__VA_ARGS__)
-#else
-#define ldebug(...)
-#endif
-
-#define IO_READ_PROTO(name) \
- uint32_t name (void *opaque, uint32_t nport)
-#define IO_WRITE_PROTO(name) \
- void name (void *opaque, uint32_t nport, uint32_t val)
-
-static const char e3[] = "COPYRIGHT (C) CREATIVE TECHNOLOGY LTD, 1992.";
-
-static struct {
- int ver_lo;
- int ver_hi;
- int irq;
- int dma;
- int hdma;
- int port;
-} conf = {5, 4, 5, 1, 5, 0x220};
-
-typedef struct SB16State {
- int irq;
- int dma;
- int hdma;
- int port;
- int ver;
-
- int in_index;
- int out_data_len;
- int fmt_stereo;
- int fmt_signed;
- int fmt_bits;
- audfmt_e fmt;
- int dma_auto;
- int block_size;
- int fifo;
- int freq;
- int time_const;
- int speaker;
- int needed_bytes;
- int cmd;
- int use_hdma;
- int highspeed;
- int can_write;
-
- int v2x6;
-
- uint8_t csp_param;
- uint8_t csp_value;
- uint8_t csp_mode;
- uint8_t csp_regs[256];
- uint8_t csp_index;
- uint8_t csp_reg83[4];
- int csp_reg83r;
- int csp_reg83w;
-
- uint8_t in2_data[10];
- uint8_t out_data[50];
- uint8_t test_reg;
- uint8_t last_read_byte;
- int nzero;
-
- int left_till_irq;
-
- int dma_running;
- int bytes_per_second;
- int align;
- SWVoice *voice;
-
- QEMUTimer *ts, *aux_ts;
- /* mixer state */
- int mixer_nreg;
- uint8_t mixer_regs[256];
-} SB16State;
-
-/* XXX: suppress that and use a context */
-static struct SB16State dsp;
-
-static int magic_of_irq (int irq)
-{
- switch (irq) {
- case 5:
- return 2;
- case 7:
- return 4;
- case 9:
- return 1;
- case 10:
- return 8;
- default:
- dolog ("bad irq %d\n", irq);
- return 2;
- }
-}
-
-static int irq_of_magic (int magic)
-{
- switch (magic) {
- case 1:
- return 9;
- case 2:
- return 5;
- case 4:
- return 7;
- case 8:
- return 10;
- default:
- dolog ("bad irq magic %d\n", magic);
- return -1;
- }
-}
-
-#if 0
-static void log_dsp (SB16State *dsp)
-{
- ldebug ("%s:%s:%d:%s:dmasize=%d:freq=%d:const=%d:speaker=%d\n",
- dsp->fmt_stereo ? "Stereo" : "Mono",
- dsp->fmt_signed ? "Signed" : "Unsigned",
- dsp->fmt_bits,
- dsp->dma_auto ? "Auto" : "Single",
- dsp->block_size,
- dsp->freq,
- dsp->time_const,
- dsp->speaker);
-}
-#endif
-
-static void speaker (SB16State *s, int on)
-{
- s->speaker = on;
- /* AUD_enable (s->voice, on); */
-}
-
-static void control (SB16State *s, int hold)
-{
- int dma = s->use_hdma ? s->hdma : s->dma;
- s->dma_running = hold;
-
- ldebug ("hold %d high %d dma %d\n", hold, s->use_hdma, dma);
-
- if (hold) {
- DMA_hold_DREQ (dma);
- AUD_enable (s->voice, 1);
- }
- else {
- DMA_release_DREQ (dma);
- AUD_enable (s->voice, 0);
- }
-}
-
-static void aux_timer (void *opaque)
-{
- SB16State *s = opaque;
- s->can_write = 1;
- pic_set_irq (s->irq, 1);
-}
-
-#define DMA8_AUTO 1
-#define DMA8_HIGH 2
-
-static void dma_cmd8 (SB16State *s, int mask, int dma_len)
-{
- s->fmt = AUD_FMT_U8;
- s->use_hdma = 0;
- s->fmt_bits = 8;
- s->fmt_signed = 0;
- s->fmt_stereo = (s->mixer_regs[0x0e] & 2) != 0;
- if (-1 == s->time_const) {
- s->freq = 11025;
- }
- else {
- int tmp = (256 - s->time_const);
- s->freq = (1000000 + (tmp / 2)) / tmp;
- }
-
- if (dma_len != -1)
- s->block_size = dma_len << s->fmt_stereo;
- else {
- /* This is apparently the only way to make both Act1/PL
- and SecondReality/FC work
-
- Act1 sets block size via command 0x48 and it's an odd number
- SR does the same with even number
- Both use stereo, and Creatives own documentation states that
- 0x48 sets block size in bytes less one.. go figure */
- s->block_size &= ~s->fmt_stereo;
- }
-
- s->freq >>= s->fmt_stereo;
- s->left_till_irq = s->block_size;
- s->bytes_per_second = (s->freq << s->fmt_stereo);
- /* s->highspeed = (mask & DMA8_HIGH) != 0; */
- s->dma_auto = (mask & DMA8_AUTO) != 0;
- s->align = (1 << s->fmt_stereo) - 1;
-
- if (s->block_size & s->align)
- dolog ("warning: unaligned buffer\n");
-
- ldebug ("freq %d, stereo %d, sign %d, bits %d, "
- "dma %d, auto %d, fifo %d, high %d\n",
- s->freq, s->fmt_stereo, s->fmt_signed, s->fmt_bits,
- s->block_size, s->dma_auto, s->fifo, s->highspeed);
-
- if (s->freq)
- s->voice = AUD_open (s->voice, "sb16", s->freq,
- 1 << s->fmt_stereo, s->fmt);
-
- control (s, 1);
- speaker (s, 1);
-}
-
-static void dma_cmd (SB16State *s, uint8_t cmd, uint8_t d0, int dma_len)
-{
- s->use_hdma = cmd < 0xc0;
- s->fifo = (cmd >> 1) & 1;
- s->dma_auto = (cmd >> 2) & 1;
- s->fmt_signed = (d0 >> 4) & 1;
- s->fmt_stereo = (d0 >> 5) & 1;
-
- switch (cmd >> 4) {
- case 11:
- s->fmt_bits = 16;
- break;
-
- case 12:
- s->fmt_bits = 8;
- break;
- }
-
- if (-1 != s->time_const) {
-#if 1
- int tmp = 256 - s->time_const;
- s->freq = (1000000 + (tmp / 2)) / tmp;
-#else
- /* s->freq = 1000000 / ((255 - s->time_const) << s->fmt_stereo); */
- s->freq = 1000000 / ((255 - s->time_const));
-#endif
- s->time_const = -1;
- }
-
- s->block_size = dma_len + 1;
- s->block_size <<= (s->fmt_bits == 16);
- if (!s->dma_auto) {
- /* It is clear that for DOOM and auto-init this value
- shouldn't take stereo into account, while Miles Sound Systems
- setsound.exe with single transfer mode wouldn't work without it
- wonders of SB16 yet again */
- s->block_size <<= s->fmt_stereo;
- }
-
- ldebug ("freq %d, stereo %d, sign %d, bits %d, "
- "dma %d, auto %d, fifo %d, high %d\n",
- s->freq, s->fmt_stereo, s->fmt_signed, s->fmt_bits,
- s->block_size, s->dma_auto, s->fifo, s->highspeed);
-
- if (16 == s->fmt_bits) {
- if (s->fmt_signed) {
- s->fmt = AUD_FMT_S16;
- }
- else {
- s->fmt = AUD_FMT_U16;
- }
- }
- else {
- if (s->fmt_signed) {
- s->fmt = AUD_FMT_S8;
- }
- else {
- s->fmt = AUD_FMT_U8;
- }
- }
-
- s->left_till_irq = s->block_size;
-
- s->bytes_per_second = (s->freq << s->fmt_stereo) << (s->fmt_bits == 16);
- s->highspeed = 0;
- s->align = (1 << (s->fmt_stereo + (s->fmt_bits == 16))) - 1;
- if (s->block_size & s->align)
- dolog ("warning: unaligned buffer\n");
-
- if (s->freq)
- s->voice = AUD_open (s->voice, "sb16", s->freq,
- 1 << s->fmt_stereo, s->fmt);
-
- control (s, 1);
- speaker (s, 1);
-}
-
-static inline void dsp_out_data (SB16State *s, uint8_t val)
-{
- ldebug ("outdata %#x\n", val);
- if (s->out_data_len < sizeof (s->out_data))
- s->out_data[s->out_data_len++] = val;
-}
-
-static inline uint8_t dsp_get_data (SB16State *s)
-{
- if (s->in_index)
- return s->in2_data[--s->in_index];
- else {
- dolog ("buffer underflow\n");
- return 0;
- }
-}
-
-static void command (SB16State *s, uint8_t cmd)
-{
- ldebug ("command %#x\n", cmd);
-
- if (cmd > 0xaf && cmd < 0xd0) {
- if (cmd & 8) {
- dolog ("ADC not yet supported (command %#x)\n", cmd);
- }
-
- switch (cmd >> 4) {
- case 11:
- case 12:
- break;
- default:
- dolog ("%#x wrong bits\n", cmd);
- }
- s->needed_bytes = 3;
- }
- else {
- switch (cmd) {
- case 0x03:
- dsp_out_data (s, 0x10); /* s->csp_param); */
- goto warn;
-
- case 0x04:
- s->needed_bytes = 1;
- goto warn;
-
- case 0x05:
- s->needed_bytes = 2;
- goto warn;
-
- case 0x08:
- /* __asm__ ("int3"); */
- goto warn;
-
- case 0x0e:
- s->needed_bytes = 2;
- goto warn;
-
- case 0x09:
- dsp_out_data (s, 0xf8);
- goto warn;
-
- case 0x0f:
- s->needed_bytes = 1;
- goto warn;
-
- case 0x10:
- s->needed_bytes = 1;
- goto warn;
-
- case 0x14:
- s->needed_bytes = 2;
- s->block_size = 0;
- break;
-
- case 0x1c: /* Auto-Initialize DMA DAC, 8-bit */
- control (s, 1);
- break;
-
- case 0x20: /* Direct ADC, Juice/PL */
- dsp_out_data (s, 0xff);
- goto warn;
-
- case 0x35:
- dolog ("MIDI command(0x35) not implemented\n");
- break;
-
- case 0x40:
- s->freq = -1;
- s->time_const = -1;
- s->needed_bytes = 1;
- break;
-
- case 0x41:
- s->freq = -1;
- s->time_const = -1;
- s->needed_bytes = 2;
- break;
-
- case 0x42:
- s->freq = -1;
- s->time_const = -1;
- s->needed_bytes = 2;
- goto warn;
-
- case 0x45:
- dsp_out_data (s, 0xaa);
- goto warn;
-
- case 0x47: /* Continue Auto-Initialize DMA 16bit */
- break;
-
- case 0x48:
- s->needed_bytes = 2;
- break;
-
- case 0x80:
- s->needed_bytes = 2;
- break;
-
- case 0x90:
- case 0x91:
- dma_cmd8 (s, ((cmd & 1) == 0) | DMA8_HIGH, -1);
- break;
-
- case 0xd0: /* halt DMA operation. 8bit */
- control (s, 0);
- break;
-
- case 0xd1: /* speaker on */
- speaker (s, 1);
- break;
-
- case 0xd3: /* speaker off */
- speaker (s, 0);
- break;
-
- case 0xd4: /* continue DMA operation. 8bit */
- control (s, 1);
- break;
-
- case 0xd5: /* halt DMA operation. 16bit */
- control (s, 0);
- break;
-
- case 0xd6: /* continue DMA operation. 16bit */
- control (s, 1);
- break;
-
- case 0xd9: /* exit auto-init DMA after this block. 16bit */
- s->dma_auto = 0;
- break;
-
- case 0xda: /* exit auto-init DMA after this block. 8bit */
- s->dma_auto = 0;
- break;
-
- case 0xe0:
- s->needed_bytes = 1;
- goto warn;
-
- case 0xe1:
- dsp_out_data (s, s->ver & 0xff);
- dsp_out_data (s, s->ver >> 8);
- break;
-
- case 0xe2:
- s->needed_bytes = 1;
- goto warn;
-
- case 0xe3:
- {
- int i;
- for (i = sizeof (e3) - 1; i >= 0; --i)
- dsp_out_data (s, e3[i]);
- }
- break;
-
- case 0xe4: /* write test reg */
- s->needed_bytes = 1;
- break;
-
- case 0xe7:
- dolog ("Attempt to probe for ESS (0xe7)?\n");
- return;
-
- case 0xe8: /* read test reg */
- dsp_out_data (s, s->test_reg);
- break;
-
- case 0xf2:
- case 0xf3:
- dsp_out_data (s, 0xaa);
- s->mixer_regs[0x82] |= (cmd == 0xf2) ? 1 : 2;
- pic_set_irq (s->irq, 1);
- break;
-
- case 0xf9:
- s->needed_bytes = 1;
- goto warn;
-
- case 0xfa:
- dsp_out_data (s, 0);
- goto warn;
-
- case 0xfc: /* FIXME */
- dsp_out_data (s, 0);
- goto warn;
-
- default:
- dolog ("unrecognized command %#x\n", cmd);
- return;
- }
- }
-
- s->cmd = cmd;
- if (!s->needed_bytes)
- ldebug ("\n");
- return;
-
- warn:
- dolog ("warning: command %#x,%d is not trully understood yet\n",
- cmd, s->needed_bytes);
- s->cmd = cmd;
- return;
-}
-
-static uint16_t dsp_get_lohi (SB16State *s)
-{
- uint8_t hi = dsp_get_data (s);
- uint8_t lo = dsp_get_data (s);
- return (hi << 8) | lo;
-}
-
-static uint16_t dsp_get_hilo (SB16State *s)
-{
- uint8_t lo = dsp_get_data (s);
- uint8_t hi = dsp_get_data (s);
- return (hi << 8) | lo;
-}
-
-static void complete (SB16State *s)
-{
- int d0, d1, d2;
- ldebug ("complete command %#x, in_index %d, needed_bytes %d\n",
- s->cmd, s->in_index, s->needed_bytes);
-
- if (s->cmd > 0xaf && s->cmd < 0xd0) {
- d2 = dsp_get_data (s);
- d1 = dsp_get_data (s);
- d0 = dsp_get_data (s);
-
- if (s->cmd & 8) {
- dolog ("ADC params cmd = %#x d0 = %d, d1 = %d, d2 = %d\n",
- s->cmd, d0, d1, d2);
- }
- else {
- ldebug ("cmd = %#x d0 = %d, d1 = %d, d2 = %d\n",
- s->cmd, d0, d1, d2);
- dma_cmd (s, s->cmd, d0, d1 + (d2 << 8));
- }
- }
- else {
- switch (s->cmd) {
- case 0x04:
- s->csp_mode = dsp_get_data (s);
- s->csp_reg83r = 0;
- s->csp_reg83w = 0;
- ldebug ("CSP command 0x04: mode=%#x\n", s->csp_mode);
- break;
-
- case 0x05:
- s->csp_param = dsp_get_data (s);
- s->csp_value = dsp_get_data (s);
- ldebug ("CSP command 0x05: param=%#x value=%#x\n",
- s->csp_param,
- s->csp_value);
- break;
-
- case 0x0e:
- d0 = dsp_get_data (s);
- d1 = dsp_get_data (s);
- ldebug ("write CSP register %d <- %#x\n", d1, d0);
- if (d1 == 0x83) {
- ldebug ("0x83[%d] <- %#x\n", s->csp_reg83r, d0);
- s->csp_reg83[s->csp_reg83r % 4] = d0;
- s->csp_reg83r += 1;
- }
- else
- s->csp_regs[d1] = d0;
- break;
-
- case 0x0f:
- d0 = dsp_get_data (s);
- ldebug ("read CSP register %#x -> %#x, mode=%#x\n",
- d0, s->csp_regs[d0], s->csp_mode);
- if (d0 == 0x83) {
- ldebug ("0x83[%d] -> %#x\n",
- s->csp_reg83w,
- s->csp_reg83[s->csp_reg83w % 4]);
- dsp_out_data (s, s->csp_reg83[s->csp_reg83w % 4]);
- s->csp_reg83w += 1;
- }
- else
- dsp_out_data (s, s->csp_regs[d0]);
- break;
-
- case 0x10:
- d0 = dsp_get_data (s);
- dolog ("cmd 0x10 d0=%#x\n", d0);
- break;
-
- case 0x14:
- dma_cmd8 (s, 0, dsp_get_lohi (s) + 1);
- break;
-
- case 0x40:
- s->time_const = dsp_get_data (s);
- ldebug ("set time const %d\n", s->time_const);
- break;
-
- case 0x42: /* FT2 sets output freq with this, go figure */
- dolog ("cmd 0x42 might not do what it think it should\n");
-
- case 0x41:
- s->freq = dsp_get_hilo (s);
- ldebug ("set freq %d\n", s->freq);
- break;
-
- case 0x48:
- s->block_size = dsp_get_lohi (s) + 1;
- ldebug ("set dma block len %d\n", s->block_size);
- break;
-
- case 0x80:
- {
- int freq, samples, bytes;
- int64_t ticks;
-
- freq = s->freq > 0 ? s->freq : 11025;
- samples = dsp_get_lohi (s) + 1;
- bytes = samples << s->fmt_stereo << (s->fmt_bits == 16);
- ticks = (bytes * ticks_per_sec) / freq;
- if (ticks < ticks_per_sec / 1024)
- pic_set_irq (s->irq, 1);
- else
- qemu_mod_timer (s->aux_ts, qemu_get_clock (vm_clock) + ticks);
- ldebug ("mix silence %d %d %lld\n", samples, bytes, ticks);
- }
- break;
-
- case 0xe0:
- d0 = dsp_get_data (s);
- s->out_data_len = 0;
- ldebug ("E0 data = %#x\n", d0);
- dsp_out_data(s, ~d0);
- break;
-
- case 0xe2:
- d0 = dsp_get_data (s);
- ldebug ("E2 = %#x\n", d0);
- break;
-
- case 0xe4:
- s->test_reg = dsp_get_data (s);
- break;
-
- case 0xf9:
- d0 = dsp_get_data (s);
- ldebug ("command 0xf9 with %#x\n", d0);
- switch (d0) {
- case 0x0e:
- dsp_out_data (s, 0xff);
- break;
-
- case 0x0f:
- dsp_out_data (s, 0x07);
- break;
-
- case 0x37:
- dsp_out_data (s, 0x38);
- break;
-
- default:
- dsp_out_data (s, 0x00);
- break;
- }
- break;
-
- default:
- dolog ("complete: unrecognized command %#x\n", s->cmd);
- return;
- }
- }
-
- ldebug ("\n");
- s->cmd = -1;
- return;
-}
-
-static void reset (SB16State *s)
-{
- pic_set_irq (s->irq, 0);
- if (s->dma_auto) {
- pic_set_irq (s->irq, 1);
- pic_set_irq (s->irq, 0);
- }
-
- s->mixer_regs[0x82] = 0;
- s->dma_auto = 0;
- s->in_index = 0;
- s->out_data_len = 0;
- s->left_till_irq = 0;
- s->needed_bytes = 0;
- s->block_size = -1;
- s->nzero = 0;
- s->highspeed = 0;
- s->v2x6 = 0;
-
- dsp_out_data(s, 0xaa);
- speaker (s, 0);
- control (s, 0);
-}
-
-static IO_WRITE_PROTO (dsp_write)
-{
- SB16State *s = opaque;
- int iport;
-
- iport = nport - s->port;
-
- ldebug ("write %#x <- %#x\n", nport, val);
- switch (iport) {
- case 0x06:
- switch (val) {
- case 0x00:
- if (s->v2x6 == 1) {
- if (0 && s->highspeed) {
- s->highspeed = 0;
- pic_set_irq (s->irq, 0);
- control (s, 0);
- }
- else
- reset (s);
- }
- s->v2x6 = 0;
- break;
-
- case 0x01:
- case 0x03: /* FreeBSD kludge */
- s->v2x6 = 1;
- break;
-
- case 0xc6:
- s->v2x6 = 0; /* Prince of Persia, csp.sys, diagnose.exe */
- break;
-
- case 0xb8: /* Panic */
- reset (s);
- break;
-
- case 0x39:
- dsp_out_data (s, 0x38);
- reset (s);
- s->v2x6 = 0x39;
- break;
-
- default:
- s->v2x6 = val;
- break;
- }
- break;
-
- case 0x0c: /* write data or command | write status */
-/* if (s->highspeed) */
-/* break; */
-
- if (0 == s->needed_bytes) {
- command (s, val);
-#if 0
- if (0 == s->needed_bytes) {
- log_dsp (s);
- }
-#endif
- }
- else {
- if (s->in_index == sizeof (s->in2_data)) {
- dolog ("in data overrun\n");
- }
- else {
- s->in2_data[s->in_index++] = val;
- if (s->in_index == s->needed_bytes) {
- s->needed_bytes = 0;
- complete (s);
-#if 0
- log_dsp (s);
-#endif
- }
- }
- }
- break;
-
- default:
- ldebug ("(nport=%#x, val=%#x)\n", nport, val);
- break;
- }
-}
-
-static IO_READ_PROTO (dsp_read)
-{
- SB16State *s = opaque;
- int iport, retval, ack = 0;
-
- iport = nport - s->port;
-
- switch (iport) {
- case 0x06: /* reset */
- retval = 0xff;
- break;
-
- case 0x0a: /* read data */
- if (s->out_data_len) {
- retval = s->out_data[--s->out_data_len];
- s->last_read_byte = retval;
- }
- else {
- dolog ("empty output buffer\n");
- retval = s->last_read_byte;
- /* goto error; */
- }
- break;
-
- case 0x0c: /* 0 can write */
- retval = s->can_write ? 0 : 0x80;
- break;
-
- case 0x0d: /* timer interrupt clear */
- /* dolog ("timer interrupt clear\n"); */
- retval = 0;
- break;
-
- case 0x0e: /* data available status | irq 8 ack */
- retval = (!s->out_data_len || s->highspeed) ? 0 : 0x80;
- if (s->mixer_regs[0x82] & 1) {
- ack = 1;
- s->mixer_regs[0x82] &= 1;
- pic_set_irq (s->irq, 0);
- }
- break;
-
- case 0x0f: /* irq 16 ack */
- retval = 0xff;
- if (s->mixer_regs[0x82] & 2) {
- ack = 1;
- s->mixer_regs[0x82] &= 2;
- pic_set_irq (s->irq, 0);
- }
- break;
-
- default:
- goto error;
- }
-
- if (!ack)
- ldebug ("read %#x -> %#x\n", nport, retval);
-
- return retval;
-
- error:
- dolog ("WARNING dsp_read %#x error\n", nport);
- return 0xff;
-}
-
-static void reset_mixer (SB16State *s)
-{
- int i;
-
- memset (s->mixer_regs, 0xff, 0x7f);
- memset (s->mixer_regs + 0x83, 0xff, sizeof (s->mixer_regs) - 0x83);
-
- s->mixer_regs[0x02] = 4; /* master volume 3bits */
- s->mixer_regs[0x06] = 4; /* MIDI volume 3bits */
- s->mixer_regs[0x08] = 0; /* CD volume 3bits */
- s->mixer_regs[0x0a] = 0; /* voice volume 2bits */
-
- /* d5=input filt, d3=lowpass filt, d1,d2=input source */
- s->mixer_regs[0x0c] = 0;
-
- /* d5=output filt, d1=stereo switch */
- s->mixer_regs[0x0e] = 0;
-
- /* voice volume L d5,d7, R d1,d3 */
- s->mixer_regs[0x04] = (4 << 5) | (4 << 1);
- /* master ... */
- s->mixer_regs[0x22] = (4 << 5) | (4 << 1);
- /* MIDI ... */
- s->mixer_regs[0x26] = (4 << 5) | (4 << 1);
-
- for (i = 0x30; i < 0x48; i++) {
- s->mixer_regs[i] = 0x20;
- }
-}
-
-static IO_WRITE_PROTO(mixer_write_indexb)
-{
- SB16State *s = opaque;
- s->mixer_nreg = val;
-}
-
-static IO_WRITE_PROTO(mixer_write_datab)
-{
- SB16State *s = opaque;
-
- ldebug ("mixer_write [%#x] <- %#x\n", s->mixer_nreg, val);
- if (s->mixer_nreg > sizeof (s->mixer_regs))
- return;
-
- switch (s->mixer_nreg) {
- case 0x00:
- reset_mixer (s);
- break;
-
- case 0x80:
- {
- int irq = irq_of_magic (val);
- ldebug ("setting irq to %d (val=%#x)\n", irq, val);
- if (irq > 0)
- s->irq = irq;
- }
- break;
-
- case 0x81:
- {
- int dma, hdma;
-
- dma = lsbindex (val & 0xf);
- hdma = lsbindex (val & 0xf0);
- dolog ("attempt to set DMA register 8bit %d, 16bit %d (val=%#x)\n",
- dma, hdma, val);
-#if 0
- s->dma = dma;
- s->hdma = hdma;
-#endif
- }
- break;
-
- case 0x82:
- dolog ("attempt to write into IRQ status register (val=%#x)\n",
- val);
- return;
-
- default:
- if (s->mixer_nreg >= 0x80)
- dolog ("attempt to write mixer[%#x] <- %#x\n", s->mixer_nreg, val);
- break;
- }
-
- s->mixer_regs[s->mixer_nreg] = val;
-}
-
-static IO_WRITE_PROTO(mixer_write_indexw)
-{
- mixer_write_indexb (opaque, nport, val & 0xff);
- mixer_write_datab (opaque, nport, (val >> 8) & 0xff);
-}
-
-static IO_READ_PROTO(mixer_read)
-{
- SB16State *s = opaque;
-#ifndef DEBUG_SB16_MOST
- if (s->mixer_nreg != 0x82)
-#endif
- ldebug ("mixer_read[%#x] -> %#x\n",
- s->mixer_nreg, s->mixer_regs[s->mixer_nreg]);
- return s->mixer_regs[s->mixer_nreg];
-}
-
-static int write_audio (SB16State *s, int nchan, int dma_pos,
- int dma_len, int len)
-{
- int temp, net;
- uint8_t tmpbuf[4096];
-
- temp = len;
- net = 0;
-
- while (temp) {
- int left = dma_len - dma_pos;
- int to_copy, copied;
-
- to_copy = audio_MIN (temp, left);
- if (to_copy > sizeof(tmpbuf))
- to_copy = sizeof(tmpbuf);
-
- copied = DMA_read_memory (nchan, tmpbuf, dma_pos, to_copy);
- copied = AUD_write (s->voice, tmpbuf, copied);
-
- temp -= copied;
- dma_pos = (dma_pos + copied) % dma_len;
- net += copied;
-
- if (!copied)
- break;
- }
-
- return net;
-}
-
-static int SB_read_DMA (void *opaque, int nchan, int dma_pos, int dma_len)
-{
- SB16State *s = opaque;
- int free, rfree, till, copy, written, elapsed;
-
- if (s->left_till_irq < 0) {
- s->left_till_irq = s->block_size;
- }
-
- elapsed = AUD_calc_elapsed (s->voice);
- free = elapsed;/* AUD_get_free (s->voice); */
- rfree = free;
- free = audio_MIN (free, elapsed) & ~s->align;
-
- if ((free <= 0) || !dma_len) {
- return dma_pos;
- }
-
- copy = free;
- till = s->left_till_irq;
-
-#ifdef DEBUG_SB16_MOST
- dolog ("pos:%06d free:%d,%d till:%d len:%d\n",
- dma_pos, free, AUD_get_free (s->voice), till, dma_len);
-#endif
-
- if (till <= copy) {
- if (0 == s->dma_auto) {
- copy = till;
- }
- }
-
- written = write_audio (s, nchan, dma_pos, dma_len, copy);
- dma_pos = (dma_pos + written) % dma_len;
- s->left_till_irq -= written;
-
- if (s->left_till_irq <= 0) {
- s->mixer_regs[0x82] |= (nchan & 4) ? 2 : 1;
- pic_set_irq (s->irq, 1);
- if (0 == s->dma_auto) {
- control (s, 0);
- speaker (s, 0);
- }
- }
-
-#ifdef DEBUG_SB16_MOST
- ldebug ("pos %5d free %5d size %5d till % 5d copy %5d written %5d size %5d\n",
- dma_pos, free, dma_len, s->left_till_irq, copy, written,
- s->block_size);
-#endif
-
- while (s->left_till_irq <= 0) {
- s->left_till_irq = s->block_size + s->left_till_irq;
- }
-
- AUD_adjust (s->voice, written);
- return dma_pos;
-}
-
-void SB_timer (void *opaque)
-{
- SB16State *s = opaque;
- AUD_run ();
- qemu_mod_timer (s->ts, qemu_get_clock (vm_clock) + 1);
-}
-
-static void SB_save (QEMUFile *f, void *opaque)
-{
- SB16State *s = opaque;
-
- qemu_put_be32s (f, &s->irq);
- qemu_put_be32s (f, &s->dma);
- qemu_put_be32s (f, &s->hdma);
- qemu_put_be32s (f, &s->port);
- qemu_put_be32s (f, &s->ver);
- qemu_put_be32s (f, &s->in_index);
- qemu_put_be32s (f, &s->out_data_len);
- qemu_put_be32s (f, &s->fmt_stereo);
- qemu_put_be32s (f, &s->fmt_signed);
- qemu_put_be32s (f, &s->fmt_bits);
- qemu_put_be32s (f, &s->fmt);
- qemu_put_be32s (f, &s->dma_auto);
- qemu_put_be32s (f, &s->block_size);
- qemu_put_be32s (f, &s->fifo);
- qemu_put_be32s (f, &s->freq);
- qemu_put_be32s (f, &s->time_const);
- qemu_put_be32s (f, &s->speaker);
- qemu_put_be32s (f, &s->needed_bytes);
- qemu_put_be32s (f, &s->cmd);
- qemu_put_be32s (f, &s->use_hdma);
- qemu_put_be32s (f, &s->highspeed);
- qemu_put_be32s (f, &s->can_write);
- qemu_put_be32s (f, &s->v2x6);
-
- qemu_put_8s (f, &s->csp_param);
- qemu_put_8s (f, &s->csp_value);
- qemu_put_8s (f, &s->csp_mode);
- qemu_put_8s (f, &s->csp_param);
- qemu_put_buffer (f, s->csp_regs, 256);
- qemu_put_8s (f, &s->csp_index);
- qemu_put_buffer (f, s->csp_reg83, 4);
- qemu_put_be32s (f, &s->csp_reg83r);
- qemu_put_be32s (f, &s->csp_reg83w);
-
- qemu_put_buffer (f, s->in2_data, sizeof (s->in2_data));
- qemu_put_buffer (f, s->out_data, sizeof (s->out_data));
- qemu_put_8s (f, &s->test_reg);
- qemu_put_8s (f, &s->last_read_byte);
-
- qemu_put_be32s (f, &s->nzero);
- qemu_put_be32s (f, &s->left_till_irq);
- qemu_put_be32s (f, &s->dma_running);
- qemu_put_be32s (f, &s->bytes_per_second);
- qemu_put_be32s (f, &s->align);
-
- qemu_put_be32s (f, &s->mixer_nreg);
- qemu_put_buffer (f, s->mixer_regs, 256);
-}
-
-static int SB_load (QEMUFile *f, void *opaque, int version_id)
-{
- SB16State *s = opaque;
-
- if (version_id != 1)
- return -EINVAL;
-
- qemu_get_be32s (f, &s->irq);
- qemu_get_be32s (f, &s->dma);
- qemu_get_be32s (f, &s->hdma);
- qemu_get_be32s (f, &s->port);
- qemu_get_be32s (f, &s->ver);
- qemu_get_be32s (f, &s->in_index);
- qemu_get_be32s (f, &s->out_data_len);
- qemu_get_be32s (f, &s->fmt_stereo);
- qemu_get_be32s (f, &s->fmt_signed);
- qemu_get_be32s (f, &s->fmt_bits);
- qemu_get_be32s (f, &s->fmt);
- qemu_get_be32s (f, &s->dma_auto);
- qemu_get_be32s (f, &s->block_size);
- qemu_get_be32s (f, &s->fifo);
- qemu_get_be32s (f, &s->freq);
- qemu_get_be32s (f, &s->time_const);
- qemu_get_be32s (f, &s->speaker);
- qemu_get_be32s (f, &s->needed_bytes);
- qemu_get_be32s (f, &s->cmd);
- qemu_get_be32s (f, &s->use_hdma);
- qemu_get_be32s (f, &s->highspeed);
- qemu_get_be32s (f, &s->can_write);
- qemu_get_be32s (f, &s->v2x6);
-
- qemu_get_8s (f, &s->csp_param);
- qemu_get_8s (f, &s->csp_value);
- qemu_get_8s (f, &s->csp_mode);
- qemu_get_8s (f, &s->csp_param);
- qemu_get_buffer (f, s->csp_regs, 256);
- qemu_get_8s (f, &s->csp_index);
- qemu_get_buffer (f, s->csp_reg83, 4);
- qemu_get_be32s (f, &s->csp_reg83r);
- qemu_get_be32s (f, &s->csp_reg83w);
-
- qemu_get_buffer (f, s->in2_data, sizeof (s->in2_data));
- qemu_get_buffer (f, s->out_data, sizeof (s->out_data));
- qemu_get_8s (f, &s->test_reg);
- qemu_get_8s (f, &s->last_read_byte);
-
- qemu_get_be32s (f, &s->nzero);
- qemu_get_be32s (f, &s->left_till_irq);
- qemu_get_be32s (f, &s->dma_running);
- qemu_get_be32s (f, &s->bytes_per_second);
- qemu_get_be32s (f, &s->align);
-
- qemu_get_be32s (f, &s->mixer_nreg);
- qemu_get_buffer (f, s->mixer_regs, 256);
-
- if (s->voice) {
- AUD_close (s->voice);
- s->voice = NULL;
- }
-
- if (s->dma_running) {
- if (s->freq)
- s->voice = AUD_open (s->voice, "sb16", s->freq,
- 1 << s->fmt_stereo, s->fmt);
-
- control (s, 1);
- speaker (s, s->speaker);
- }
- return 0;
-}
-
-void SB16_init (void)
-{
- SB16State *s = &dsp;
- int i;
- static const uint8_t dsp_write_ports[] = {0x6, 0xc};
- static const uint8_t dsp_read_ports[] = {0x6, 0xa, 0xc, 0xd, 0xe, 0xf};
-
- s->ts = qemu_new_timer (vm_clock, SB_timer, s);
- if (!s->ts)
- return;
-
- s->irq = conf.irq;
- s->dma = conf.dma;
- s->hdma = conf.hdma;
- s->port = conf.port;
- s->ver = conf.ver_lo | (conf.ver_hi << 8);
-
- s->mixer_regs[0x80] = magic_of_irq (s->irq);
- s->mixer_regs[0x81] = (1 << s->dma) | (1 << s->hdma);
- s->mixer_regs[0x82] = 2 << 5;
-
- s->csp_regs[5] = 1;
- s->csp_regs[9] = 0xf8;
-
- reset_mixer (s);
- s->aux_ts = qemu_new_timer (vm_clock, aux_timer, s);
- if (!s->aux_ts)
- return;
-
- for (i = 0; i < LENOFA (dsp_write_ports); i++) {
- register_ioport_write (s->port + dsp_write_ports[i], 1, 1, dsp_write, s);
- }
-
- for (i = 0; i < LENOFA (dsp_read_ports); i++) {
- register_ioport_read (s->port + dsp_read_ports[i], 1, 1, dsp_read, s);
- }
-
- register_ioport_write (s->port + 0x4, 1, 1, mixer_write_indexb, s);
- register_ioport_write (s->port + 0x4, 1, 2, mixer_write_indexw, s);
- register_ioport_read (s->port + 0x5, 1, 1, mixer_read, s);
- register_ioport_write (s->port + 0x5, 1, 1, mixer_write_datab, s);
-
- DMA_register_channel (s->hdma, SB_read_DMA, s);
- DMA_register_channel (s->dma, SB_read_DMA, s);
- s->can_write = 1;
-
- qemu_mod_timer (s->ts, qemu_get_clock (vm_clock) + 1);
- register_savevm ("sb16", 0, 1, SB_save, SB_load, s);
-}
+++ /dev/null
-/*
- * QEMU interrupt controller emulation
- *
- * Copyright (c) 2003-2004 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "vl.h"
-//#define DEBUG_IRQ_COUNT
-
-/* These registers are used for sending/receiving irqs from/to
- * different cpu's.
- */
-struct sun4m_intreg_percpu {
- unsigned int tbt; /* Intrs pending for this cpu, by PIL. */
- /* These next two registers are WRITE-ONLY and are only
- * "on bit" sensitive, "off bits" written have NO affect.
- */
- unsigned int clear; /* Clear this cpus irqs here. */
- unsigned int set; /* Set this cpus irqs here. */
-};
-/*
- * djhr
- * Actually the clear and set fields in this struct are misleading..
- * according to the SLAVIO manual (and the same applies for the SEC)
- * the clear field clears bits in the mask which will ENABLE that IRQ
- * the set field sets bits in the mask to DISABLE the IRQ.
- *
- * Also the undirected_xx address in the SLAVIO is defined as
- * RESERVED and write only..
- *
- * DAVEM_NOTE: The SLAVIO only specifies behavior on uniprocessor
- * sun4m machines, for MP the layout makes more sense.
- */
-struct sun4m_intreg_master {
- unsigned int tbt; /* IRQ's that are pending, see sun4m masks. */
- unsigned int irqs; /* Master IRQ bits. */
-
- /* Again, like the above, two these registers are WRITE-ONLY. */
- unsigned int clear; /* Clear master IRQ's by setting bits here. */
- unsigned int set; /* Set master IRQ's by setting bits here. */
-
- /* This register is both READ and WRITE. */
- unsigned int undirected_target; /* Which cpu gets undirected irqs. */
-};
-
-#define SUN4M_INT_ENABLE 0x80000000
-#define SUN4M_INT_E14 0x00000080
-#define SUN4M_INT_E10 0x00080000
-
-#define SUN4M_HARD_INT(x) (0x000000001 << (x))
-#define SUN4M_SOFT_INT(x) (0x000010000 << (x))
-
-#define SUN4M_INT_MASKALL 0x80000000 /* mask all interrupts */
-#define SUN4M_INT_MODULE_ERR 0x40000000 /* module error */
-#define SUN4M_INT_M2S_WRITE 0x20000000 /* write buffer error */
-#define SUN4M_INT_ECC 0x10000000 /* ecc memory error */
-#define SUN4M_INT_FLOPPY 0x00400000 /* floppy disk */
-#define SUN4M_INT_MODULE 0x00200000 /* module interrupt */
-#define SUN4M_INT_VIDEO 0x00100000 /* onboard video */
-#define SUN4M_INT_REALTIME 0x00080000 /* system timer */
-#define SUN4M_INT_SCSI 0x00040000 /* onboard scsi */
-#define SUN4M_INT_AUDIO 0x00020000 /* audio/isdn */
-#define SUN4M_INT_ETHERNET 0x00010000 /* onboard ethernet */
-#define SUN4M_INT_SERIAL 0x00008000 /* serial ports */
-#define SUN4M_INT_SBUSBITS 0x00003F80 /* sbus int bits */
-
-#define SUN4M_INT_SBUS(x) (1 << (x+7))
-#define SUN4M_INT_VME(x) (1 << (x))
-
-typedef struct SCHEDState {
- uint32_t addr, addrg;
- uint32_t intreg_pending;
- uint32_t intreg_enabled;
- uint32_t intregm_pending;
- uint32_t intregm_enabled;
-} SCHEDState;
-
-static SCHEDState *ps;
-
-#ifdef DEBUG_IRQ_COUNT
-static uint64_t irq_count[32];
-#endif
-
-static uint32_t intreg_mem_readl(void *opaque, target_phys_addr_t addr)
-{
- SCHEDState *s = opaque;
- uint32_t saddr;
-
- saddr = (addr - s->addr) >> 2;
- switch (saddr) {
- case 0:
- return s->intreg_pending;
- break;
- default:
- break;
- }
- return 0;
-}
-
-static void intreg_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
- SCHEDState *s = opaque;
- uint32_t saddr;
-
- saddr = (addr - s->addr) >> 2;
- switch (saddr) {
- case 0:
- s->intreg_pending = val;
- break;
- case 1: // clear
- s->intreg_enabled &= ~val;
- break;
- case 2: // set
- s->intreg_enabled |= val;
- break;
- default:
- break;
- }
-}
-
-static CPUReadMemoryFunc *intreg_mem_read[3] = {
- intreg_mem_readl,
- intreg_mem_readl,
- intreg_mem_readl,
-};
-
-static CPUWriteMemoryFunc *intreg_mem_write[3] = {
- intreg_mem_writel,
- intreg_mem_writel,
- intreg_mem_writel,
-};
-
-static uint32_t intregm_mem_readl(void *opaque, target_phys_addr_t addr)
-{
- SCHEDState *s = opaque;
- uint32_t saddr;
-
- saddr = (addr - s->addrg) >> 2;
- switch (saddr) {
- case 0:
- return s->intregm_pending;
- break;
- case 1:
- return s->intregm_enabled;
- break;
- default:
- break;
- }
- return 0;
-}
-
-static void intregm_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
- SCHEDState *s = opaque;
- uint32_t saddr;
-
- saddr = (addr - s->addrg) >> 2;
- switch (saddr) {
- case 0:
- s->intregm_pending = val;
- break;
- case 1:
- s->intregm_enabled = val;
- break;
- case 2: // clear
- s->intregm_enabled &= ~val;
- break;
- case 3: // set
- s->intregm_enabled |= val;
- break;
- default:
- break;
- }
-}
-
-static CPUReadMemoryFunc *intregm_mem_read[3] = {
- intregm_mem_readl,
- intregm_mem_readl,
- intregm_mem_readl,
-};
-
-static CPUWriteMemoryFunc *intregm_mem_write[3] = {
- intregm_mem_writel,
- intregm_mem_writel,
- intregm_mem_writel,
-};
-
-void pic_info(void)
-{
- term_printf("per-cpu: pending 0x%08x, enabled 0x%08x\n", ps->intreg_pending, ps->intreg_enabled);
- term_printf("master: pending 0x%08x, enabled 0x%08x\n", ps->intregm_pending, ps->intregm_enabled);
-}
-
-void irq_info(void)
-{
-#ifndef DEBUG_IRQ_COUNT
- term_printf("irq statistic code not compiled.\n");
-#else
- int i;
- int64_t count;
-
- term_printf("IRQ statistics:\n");
- for (i = 0; i < 32; i++) {
- count = irq_count[i];
- if (count > 0)
- term_printf("%2d: %lld\n", i, count);
- }
-#endif
-}
-
-static const unsigned int intr_to_mask[16] = {
- 0, 0, 0, 0, 0, 0, SUN4M_INT_ETHERNET, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
-};
-
-void pic_set_irq(int irq, int level)
-{
- if (irq < 16) {
- unsigned int mask = intr_to_mask[irq];
- ps->intreg_pending |= 1 << irq;
- if (ps->intregm_enabled & mask) {
- cpu_single_env->interrupt_index = irq;
- cpu_interrupt(cpu_single_env, CPU_INTERRUPT_HARD);
- }
- }
-#ifdef DEBUG_IRQ_COUNT
- if (level == 1)
- irq_count[irq]++;
-#endif
-}
-
-void sched_init(uint32_t addr, uint32_t addrg)
-{
- int intreg_io_memory, intregm_io_memory;
- SCHEDState *s;
-
- s = qemu_mallocz(sizeof(SCHEDState));
- if (!s)
- return;
- s->addr = addr;
- s->addrg = addrg;
-
- intreg_io_memory = cpu_register_io_memory(0, intreg_mem_read, intreg_mem_write, s);
- cpu_register_physical_memory(addr, 3, intreg_io_memory);
-
- intregm_io_memory = cpu_register_io_memory(0, intregm_mem_read, intregm_mem_write, s);
- cpu_register_physical_memory(addrg, 5, intregm_io_memory);
-
- ps = s;
-}
-
+++ /dev/null
-/*
- * QEMU 16450 UART emulation
- *
- * Copyright (c) 2003-2004 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "vl.h"
-
-//#define DEBUG_SERIAL
-
-#define UART_LCR_DLAB 0x80 /* Divisor latch access bit */
-
-#define UART_IER_MSI 0x08 /* Enable Modem status interrupt */
-#define UART_IER_RLSI 0x04 /* Enable receiver line status interrupt */
-#define UART_IER_THRI 0x02 /* Enable Transmitter holding register int. */
-#define UART_IER_RDI 0x01 /* Enable receiver data interrupt */
-
-#define UART_IIR_NO_INT 0x01 /* No interrupts pending */
-#define UART_IIR_ID 0x06 /* Mask for the interrupt ID */
-
-#define UART_IIR_MSI 0x00 /* Modem status interrupt */
-#define UART_IIR_THRI 0x02 /* Transmitter holding register empty */
-#define UART_IIR_RDI 0x04 /* Receiver data interrupt */
-#define UART_IIR_RLSI 0x06 /* Receiver line status interrupt */
-
-/*
- * These are the definitions for the Modem Control Register
- */
-#define UART_MCR_LOOP 0x10 /* Enable loopback test mode */
-#define UART_MCR_OUT2 0x08 /* Out2 complement */
-#define UART_MCR_OUT1 0x04 /* Out1 complement */
-#define UART_MCR_RTS 0x02 /* RTS complement */
-#define UART_MCR_DTR 0x01 /* DTR complement */
-
-/*
- * These are the definitions for the Modem Status Register
- */
-#define UART_MSR_DCD 0x80 /* Data Carrier Detect */
-#define UART_MSR_RI 0x40 /* Ring Indicator */
-#define UART_MSR_DSR 0x20 /* Data Set Ready */
-#define UART_MSR_CTS 0x10 /* Clear to Send */
-#define UART_MSR_DDCD 0x08 /* Delta DCD */
-#define UART_MSR_TERI 0x04 /* Trailing edge ring indicator */
-#define UART_MSR_DDSR 0x02 /* Delta DSR */
-#define UART_MSR_DCTS 0x01 /* Delta CTS */
-#define UART_MSR_ANY_DELTA 0x0F /* Any of the delta bits! */
-
-#define UART_LSR_TEMT 0x40 /* Transmitter empty */
-#define UART_LSR_THRE 0x20 /* Transmit-hold-register empty */
-#define UART_LSR_BI 0x10 /* Break interrupt indicator */
-#define UART_LSR_FE 0x08 /* Frame error indicator */
-#define UART_LSR_PE 0x04 /* Parity error indicator */
-#define UART_LSR_OE 0x02 /* Overrun error indicator */
-#define UART_LSR_DR 0x01 /* Receiver data ready */
-
-/*
- * Size of ring buffer for characters to send to host
- */
-#define MAXCHRS 256
-
-struct SerialState {
- uint8_t divider;
- uint8_t rbr; /* receive register */
- uint8_t ier;
- uint8_t iir; /* read only */
- uint8_t lcr;
- uint8_t mcr;
- uint8_t lsr; /* read only */
- uint8_t msr;
- uint8_t scr;
- /* NOTE: this hidden state is necessary for tx irq generation as
- it can be reset while reading iir */
- int thr_ipending;
- int irq;
- struct cbuf {
- uint8_t buf[MAXCHRS];
- int in;
- int out;
- } cbuf;
- CharDriverState *chr;
-};
-
-static void serial_update_irq(SerialState *s)
-{
- if ((s->lsr & UART_LSR_DR) == 0 && s->cbuf.in != s->cbuf.out) {
- s->rbr = s->cbuf.buf[s->cbuf.out++];
- if (s->cbuf.out >= MAXCHRS)
- s->cbuf.out = 0;
- s->lsr |= UART_LSR_DR;
- }
- if ((s->lsr & UART_LSR_DR) && (s->ier & UART_IER_RDI)) {
- s->iir = UART_IIR_RDI;
- } else if (s->thr_ipending && (s->ier & UART_IER_THRI)) {
- s->iir = UART_IIR_THRI;
- } else {
- s->iir = UART_IIR_NO_INT;
- }
- if (s->iir != UART_IIR_NO_INT) {
- pic_set_irq(s->irq, 1);
- } else {
- pic_set_irq(s->irq, 0);
- }
-}
-
-static void serial_ioport_write(void *opaque, uint32_t addr, uint32_t val)
-{
- SerialState *s = opaque;
- unsigned char ch;
-
- addr &= 7;
-#ifdef DEBUG_SERIAL
- printf("serial: write addr=0x%02x val=0x%02x\n", addr, val);
-#endif
- switch(addr) {
- default:
- case 0:
- if (s->lcr & UART_LCR_DLAB) {
- s->divider = (s->divider & 0xff00) | val;
- } else {
- s->thr_ipending = 0;
- s->lsr &= ~UART_LSR_THRE;
- serial_update_irq(s);
- ch = val;
- qemu_chr_write(s->chr, &ch, 1);
- s->thr_ipending = 1;
- s->lsr |= UART_LSR_THRE;
- s->lsr |= UART_LSR_TEMT;
- serial_update_irq(s);
- }
- break;
- case 1:
- if (s->lcr & UART_LCR_DLAB) {
- s->divider = (s->divider & 0x00ff) | (val << 8);
- } else {
- s->ier = val & 0x0f;
- if (s->lsr & UART_LSR_THRE) {
- s->thr_ipending = 1;
- }
- serial_update_irq(s);
- }
- break;
- case 2:
- break;
- case 3:
- s->lcr = val;
- break;
- case 4:
- s->mcr = val & 0x1f;
- break;
- case 5:
- break;
- case 6:
- s->msr = val;
- break;
- case 7:
- s->scr = val;
- break;
- }
-}
-
-static uint32_t serial_ioport_read(void *opaque, uint32_t addr)
-{
- SerialState *s = opaque;
- uint32_t ret;
-
- addr &= 7;
- switch(addr) {
- default:
- case 0:
- if (s->lcr & UART_LCR_DLAB) {
- ret = s->divider & 0xff;
- } else {
- ret = s->rbr;
- s->lsr &= ~(UART_LSR_DR | UART_LSR_BI);
- serial_update_irq(s);
- }
- break;
- case 1:
- if (s->lcr & UART_LCR_DLAB) {
- ret = (s->divider >> 8) & 0xff;
- } else {
- ret = s->ier;
- }
- break;
- case 2:
- ret = s->iir;
- /* reset THR pending bit */
- if ((ret & 0x7) == UART_IIR_THRI)
- s->thr_ipending = 0;
- serial_update_irq(s);
- break;
- case 3:
- ret = s->lcr;
- break;
- case 4:
- ret = s->mcr;
- break;
- case 5:
- ret = s->lsr;
- break;
- case 6:
- if (s->mcr & UART_MCR_LOOP) {
- /* in loopback, the modem output pins are connected to the
- inputs */
- ret = (s->mcr & 0x0c) << 4;
- ret |= (s->mcr & 0x02) << 3;
- ret |= (s->mcr & 0x01) << 5;
- } else {
- ret = s->msr;
- }
- break;
- case 7:
- ret = s->scr;
- break;
- }
-#ifdef DEBUG_SERIAL
- printf("serial: read addr=0x%02x val=0x%02x\n", addr, ret);
-#endif
- return ret;
-}
-
-void ser_queue(SerialState *s, unsigned char c)
-{
- int n;
-
- n = s->cbuf.in - s->cbuf.out;
- if (n < 0)
- n += MAXCHRS;
- if (n < (MAXCHRS - 1)) {
- s->cbuf.buf[s->cbuf.in++] = c;
- if (s->cbuf.in >= MAXCHRS)
- s->cbuf.in = 0;
- serial_update_irq(s);
- }
- return;
-}
-
-static int serial_can_receive(SerialState *s)
-{
- return !(s->lsr & UART_LSR_DR);
-}
-
-static void serial_receive_byte(SerialState *s, int ch)
-{
-#ifdef DEBUG_SERIAL
- printf("serial: serial_receive_byte: ch=0x%02x\n", ch);
-#endif // DEBUG_SERIAL
- s->rbr = ch;
- s->lsr |= UART_LSR_DR;
- serial_update_irq(s);
-}
-
-static void serial_receive_break(SerialState *s)
-{
- s->rbr = 0;
- s->lsr |= UART_LSR_BI | UART_LSR_DR;
- serial_update_irq(s);
-}
-
-static int serial_can_receive1(void *opaque)
-{
- SerialState *s = opaque;
- return serial_can_receive(s);
-}
-
-static void serial_receive1(void *opaque, const uint8_t *buf, int size)
-{
- SerialState *s = opaque;
- serial_receive_byte(s, buf[0]);
-}
-
-static void serial_event(void *opaque, int event)
-{
- SerialState *s = opaque;
- if (event == CHR_EVENT_BREAK)
- serial_receive_break(s);
-}
-
-/* If fd is zero, it means that the serial device uses the console */
-SerialState *serial_init(int base, int irq, CharDriverState *chr)
-{
- SerialState *s;
-
- s = qemu_mallocz(sizeof(SerialState));
- if (!s)
- return NULL;
- s->cbuf.in = 0;
- s->cbuf.out = 0;
- s->irq = irq;
- s->lsr = UART_LSR_TEMT | UART_LSR_THRE;
- s->iir = UART_IIR_NO_INT;
-
- register_ioport_write(base, 8, 1, serial_ioport_write, s);
- register_ioport_read(base, 8, 1, serial_ioport_read, s);
- s->chr = chr;
- qemu_chr_add_read_handler(chr, serial_can_receive1, serial_receive1, s);
- qemu_chr_add_event_handler(chr, serial_event);
- return s;
-}
+++ /dev/null
-/*
- * QEMU Sun4m System Emulator
- *
- * Copyright (c) 2003-2004 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "vl.h"
-#include "m48t08.h"
-
-#define KERNEL_LOAD_ADDR 0x00004000
-#define MMU_CONTEXT_TBL 0x00003000
-#define MMU_L1PTP (MMU_CONTEXT_TBL + 0x0400)
-#define MMU_L2PTP (MMU_CONTEXT_TBL + 0x0800)
-#define PROM_ADDR 0xffd04000
-#define PROM_FILENAMEB "proll.bin"
-#define PROM_FILENAMEE "proll.elf"
-#define PROLL_MAGIC_ADDR 0x20000000
-#define PHYS_JJ_EEPROM 0x71200000 /* [2000] MK48T08 */
-#define PHYS_JJ_IDPROM_OFF 0x1FD8
-#define PHYS_JJ_EEPROM_SIZE 0x2000
-#define PHYS_JJ_IOMMU 0x10000000 /* First page of sun4m IOMMU */
-#define PHYS_JJ_TCX_FB 0x50800000 /* Start address, frame buffer body */
-#define PHYS_JJ_TCX_0E 0x5E000000 /* Top address, one byte used. */
-#define PHYS_JJ_IOMMU 0x10000000 /* First page of sun4m IOMMU */
-#define PHYS_JJ_LEDMA 0x78400010 /* ledma, off by 10 from unused SCSI */
-#define PHYS_JJ_LE 0x78C00000 /* LANCE, typical sun4m */
-#define PHYS_JJ_LE_IRQ 6
-#define PHYS_JJ_CLOCK 0x71D00000
-#define PHYS_JJ_CLOCK_IRQ 10
-#define PHYS_JJ_CLOCK1 0x71D10000
-#define PHYS_JJ_CLOCK1_IRQ 14
-#define PHYS_JJ_INTR0 0x71E00000 /* CPU0 interrupt control registers */
-#define PHYS_JJ_INTR_G 0x71E10000 /* Master interrupt control registers */
-
-/* TSC handling */
-
-uint64_t cpu_get_tsc()
-{
- return qemu_get_clock(vm_clock);
-}
-
-void DMA_run() {}
-void SB16_run() {}
-int serial_can_receive(SerialState *s) { return 0; }
-void serial_receive_byte(SerialState *s, int ch) {}
-void serial_receive_break(SerialState *s) {}
-
-static m48t08_t *nvram;
-
-/* Sun4m hardware initialisation */
-void sun4m_init(int ram_size, int vga_ram_size, int boot_device,
- DisplayState *ds, const char **fd_filename, int snapshot,
- const char *kernel_filename, const char *kernel_cmdline,
- const char *initrd_filename)
-{
- char buf[1024];
- int ret, linux_boot;
- unsigned long bios_offset;
-
- linux_boot = (kernel_filename != NULL);
-
- /* allocate RAM */
- cpu_register_physical_memory(0, ram_size, 0);
- bios_offset = ram_size;
-
- iommu_init(PHYS_JJ_IOMMU);
- sched_init(PHYS_JJ_INTR0, PHYS_JJ_INTR_G);
- tcx_init(ds, PHYS_JJ_TCX_FB);
- lance_init(&nd_table[0], PHYS_JJ_LE_IRQ, PHYS_JJ_LE, PHYS_JJ_LEDMA);
- nvram = m48t08_init(PHYS_JJ_EEPROM, PHYS_JJ_EEPROM_SIZE, &nd_table[0].macaddr);
- timer_init(PHYS_JJ_CLOCK, PHYS_JJ_CLOCK_IRQ);
- timer_init(PHYS_JJ_CLOCK1, PHYS_JJ_CLOCK1_IRQ);
- magic_init(kernel_filename, phys_ram_base + KERNEL_LOAD_ADDR, PROLL_MAGIC_ADDR);
-
- /* We load Proll as the kernel and start it. It will issue a magic
- IO to load the real kernel */
- if (linux_boot) {
- snprintf(buf, sizeof(buf), "%s/%s", bios_dir, PROM_FILENAMEB);
- ret = load_kernel(buf,
- phys_ram_base + KERNEL_LOAD_ADDR);
- if (ret < 0) {
- fprintf(stderr, "qemu: could not load kernel '%s'\n",
- buf);
- exit(1);
- }
- }
- /* Setup a MMU entry for entire address space */
- stl_raw(phys_ram_base + MMU_CONTEXT_TBL, (MMU_L1PTP >> 4) | 1);
- stl_raw(phys_ram_base + MMU_L1PTP, (MMU_L2PTP >> 4) | 1);
- stl_raw(phys_ram_base + MMU_L1PTP + (0x01 << 2), (MMU_L2PTP >> 4) | 1); // 01.. == 00..
- stl_raw(phys_ram_base + MMU_L1PTP + (0xff << 2), (MMU_L2PTP >> 4) | 1); // ff.. == 00..
- stl_raw(phys_ram_base + MMU_L1PTP + (0xf0 << 2), (MMU_L2PTP >> 4) | 1); // f0.. == 00..
- /* 3 = U:RWX S:RWX */
- stl_raw(phys_ram_base + MMU_L2PTP, (3 << PTE_ACCESS_SHIFT) | 2);
- stl_raw(phys_ram_base + MMU_L2PTP, ((0x01 << PTE_PPN_SHIFT) >> 4 ) | (3 << PTE_ACCESS_SHIFT) | 2);
-}
+++ /dev/null
-/*
- * QEMU Sun4m System Emulator
- *
- * Copyright (c) 2003-2004 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "vl.h"
-
-#define MAXX 1024
-#define MAXY 768
-#define XSZ (8*80)
-#define YSZ (24*11)
-#define XOFF (MAXX-XSZ)
-#define YOFF (MAXY-YSZ)
-
-typedef struct TCXState {
- uint32_t addr;
- DisplayState *ds;
- uint8_t *vram;
-} TCXState;
-
-static TCXState *ts;
-
-void vga_update_display()
-{
- dpy_update(ts->ds, 0, 0, XSZ, YSZ);
-}
-
-void vga_invalidate_display() {}
-
-static uint32_t tcx_mem_readb(void *opaque, target_phys_addr_t addr)
-{
- TCXState *s = opaque;
- uint32_t saddr;
- unsigned int x, y;
-
- saddr = addr - s->addr - YOFF*MAXX - XOFF;
- y = saddr / MAXX;
- x = saddr - y * MAXX;
- if (x < XSZ && y < YSZ) {
- return s->vram[y * XSZ + x];
- }
- return 0;
-}
-
-static uint32_t tcx_mem_readw(void *opaque, target_phys_addr_t addr)
-{
- uint32_t v;
-#ifdef TARGET_WORDS_BIGENDIAN
- v = tcx_mem_readb(opaque, addr) << 8;
- v |= tcx_mem_readb(opaque, addr + 1);
-#else
- v = tcx_mem_readb(opaque, addr);
- v |= tcx_mem_readb(opaque, addr + 1) << 8;
-#endif
- return v;
-}
-
-static uint32_t tcx_mem_readl(void *opaque, target_phys_addr_t addr)
-{
- uint32_t v;
-#ifdef TARGET_WORDS_BIGENDIAN
- v = tcx_mem_readb(opaque, addr) << 24;
- v |= tcx_mem_readb(opaque, addr + 1) << 16;
- v |= tcx_mem_readb(opaque, addr + 2) << 8;
- v |= tcx_mem_readb(opaque, addr + 3);
-#else
- v = tcx_mem_readb(opaque, addr);
- v |= tcx_mem_readb(opaque, addr + 1) << 8;
- v |= tcx_mem_readb(opaque, addr + 2) << 16;
- v |= tcx_mem_readb(opaque, addr + 3) << 24;
-#endif
- return v;
-}
-
-static void tcx_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
- TCXState *s = opaque;
- uint32_t saddr;
- unsigned int x, y;
- char *sptr;
-
- saddr = addr - s->addr - YOFF*MAXX - XOFF;
- y = saddr / MAXX;
- x = saddr - y * MAXX;
- if (x < XSZ && y < YSZ) {
- sptr = s->ds->data;
- if (sptr) {
- if (s->ds->depth == 24 || s->ds->depth == 32) {
- /* XXX need to do CLUT translation */
- sptr[y * s->ds->linesize + x*4] = val & 0xff;
- sptr[y * s->ds->linesize + x*4+1] = val & 0xff;
- sptr[y * s->ds->linesize + x*4+2] = val & 0xff;
- }
- else if (s->ds->depth == 8) {
- sptr[y * s->ds->linesize + x] = val & 0xff;
- }
- }
- cpu_physical_memory_set_dirty(addr);
- s->vram[y * XSZ + x] = val & 0xff;
- }
-}
-
-static void tcx_mem_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
-#ifdef TARGET_WORDS_BIGENDIAN
- tcx_mem_writeb(opaque, addr, (val >> 8) & 0xff);
- tcx_mem_writeb(opaque, addr + 1, val & 0xff);
-#else
- tcx_mem_writeb(opaque, addr, val & 0xff);
- tcx_mem_writeb(opaque, addr + 1, (val >> 8) & 0xff);
-#endif
-}
-
-static void tcx_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
-#ifdef TARGET_WORDS_BIGENDIAN
- tcx_mem_writeb(opaque, addr, (val >> 24) & 0xff);
- tcx_mem_writeb(opaque, addr + 1, (val >> 16) & 0xff);
- tcx_mem_writeb(opaque, addr + 2, (val >> 8) & 0xff);
- tcx_mem_writeb(opaque, addr + 3, val & 0xff);
-#else
- tcx_mem_writeb(opaque, addr, val & 0xff);
- tcx_mem_writeb(opaque, addr + 1, (val >> 8) & 0xff);
- tcx_mem_writeb(opaque, addr + 2, (val >> 16) & 0xff);
- tcx_mem_writeb(opaque, addr + 3, (val >> 24) & 0xff);
-#endif
-}
-
-static CPUReadMemoryFunc *tcx_mem_read[3] = {
- tcx_mem_readb,
- tcx_mem_readw,
- tcx_mem_readl,
-};
-
-static CPUWriteMemoryFunc *tcx_mem_write[3] = {
- tcx_mem_writeb,
- tcx_mem_writew,
- tcx_mem_writel,
-};
-
-void tcx_init(DisplayState *ds, uint32_t addr)
-{
- TCXState *s;
- int tcx_io_memory;
-
- s = qemu_mallocz(sizeof(TCXState));
- if (!s)
- return;
- s->ds = ds;
- s->addr = addr;
- ts = s;
- tcx_io_memory = cpu_register_io_memory(0, tcx_mem_read, tcx_mem_write, s);
- cpu_register_physical_memory(addr, 0x100000,
- tcx_io_memory);
- s->vram = qemu_mallocz(XSZ*YSZ);
- dpy_resize(s->ds, XSZ, YSZ);
-}
-
-void vga_screen_dump(const char *filename)
-{
- TCXState *s = ts;
- FILE *f;
- uint8_t *d, *d1;
- unsigned int v;
- int y, x;
-
- f = fopen(filename, "wb");
- if (!f)
- return -1;
- fprintf(f, "P6\n%d %d\n%d\n",
- XSZ, YSZ, 255);
- d1 = s->vram;
- for(y = 0; y < YSZ; y++) {
- d = d1;
- for(x = 0; x < XSZ; x++) {
- v = *d;
- fputc((v) & 0xff, f);
- fputc((v) & 0xff, f);
- fputc((v) & 0xff, f);
- d++;
- }
- d1 += XSZ;
- }
- fclose(f);
- return;
-}
-
-
-
+++ /dev/null
-/*
- * QEMU Sparc timer controller emulation
- *
- * Copyright (c) 2003-2004 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "vl.h"
-
-/*
- * Registers of hardware timer in sun4m.
- */
-struct sun4m_timer_percpu {
- volatile unsigned int l14_timer_limit; /* Initial value is 0x009c4000 */
- volatile unsigned int l14_cur_count;
-};
-
-struct sun4m_timer_global {
- volatile unsigned int l10_timer_limit;
- volatile unsigned int l10_cur_count;
-};
-
-typedef struct TIMERState {
- uint32_t addr;
- uint32_t timer_regs[2];
- int irq;
-} TIMERState;
-
-static uint32_t timer_mem_readl(void *opaque, target_phys_addr_t addr)
-{
- TIMERState *s = opaque;
- uint32_t saddr;
-
- saddr = (addr - s->addr) >> 2;
- switch (saddr) {
- default:
- return s->timer_regs[saddr];
- break;
- }
- return 0;
-}
-
-static void timer_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
- TIMERState *s = opaque;
- uint32_t saddr;
-
- saddr = (addr - s->addr) >> 2;
- switch (saddr) {
- default:
- s->timer_regs[saddr] = val;
- break;
- }
-}
-
-static CPUReadMemoryFunc *timer_mem_read[3] = {
- timer_mem_readl,
- timer_mem_readl,
- timer_mem_readl,
-};
-
-static CPUWriteMemoryFunc *timer_mem_write[3] = {
- timer_mem_writel,
- timer_mem_writel,
- timer_mem_writel,
-};
-
-void timer_init(uint32_t addr, int irq)
-{
- int timer_io_memory;
- TIMERState *s;
-
- s = qemu_mallocz(sizeof(TIMERState));
- if (!s)
- return;
- s->addr = addr;
- s->irq = irq;
-
- timer_io_memory = cpu_register_io_memory(0, timer_mem_read, timer_mem_write, s);
- cpu_register_physical_memory(addr, 2, timer_io_memory);
-}
+++ /dev/null
-/*
- * QEMU USB HID devices
- *
- * Copyright (c) 2005 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "vl.h"
-
-/* HID interface requests */
-#define GET_REPORT 0xa101
-#define GET_IDLE 0xa102
-#define GET_PROTOCOL 0xa103
-#define SET_IDLE 0x210a
-#define SET_PROTOCOL 0x210b
-
-#define USB_MOUSE 1
-#define USB_TABLET 2
-
-typedef struct USBMouseState {
- USBDevice dev;
- int dx, dy, dz, buttons_state;
- int x, y;
- int kind;
- int mouse_grabbed;
-} USBMouseState;
-
-/* mostly the same values as the Bochs USB Mouse device */
-static const uint8_t qemu_mouse_dev_descriptor[] = {
- 0x12, /* u8 bLength; */
- 0x01, /* u8 bDescriptorType; Device */
- 0x10, 0x00, /* u16 bcdUSB; v1.0 */
-
- 0x00, /* u8 bDeviceClass; */
- 0x00, /* u8 bDeviceSubClass; */
- 0x00, /* u8 bDeviceProtocol; [ low/full speeds only ] */
- 0x08, /* u8 bMaxPacketSize0; 8 Bytes */
-
- 0x27, 0x06, /* u16 idVendor; */
- 0x01, 0x00, /* u16 idProduct; */
- 0x00, 0x00, /* u16 bcdDevice */
-
- 0x03, /* u8 iManufacturer; */
- 0x02, /* u8 iProduct; */
- 0x01, /* u8 iSerialNumber; */
- 0x01 /* u8 bNumConfigurations; */
-};
-
-static const uint8_t qemu_mouse_config_descriptor[] = {
- /* one configuration */
- 0x09, /* u8 bLength; */
- 0x02, /* u8 bDescriptorType; Configuration */
- 0x22, 0x00, /* u16 wTotalLength; */
- 0x01, /* u8 bNumInterfaces; (1) */
- 0x01, /* u8 bConfigurationValue; */
- 0x04, /* u8 iConfiguration; */
- 0xa0, /* u8 bmAttributes;
- Bit 7: must be set,
- 6: Self-powered,
- 5: Remote wakeup,
- 4..0: resvd */
- 50, /* u8 MaxPower; */
-
- /* USB 1.1:
- * USB 2.0, single TT organization (mandatory):
- * one interface, protocol 0
- *
- * USB 2.0, multiple TT organization (optional):
- * two interfaces, protocols 1 (like single TT)
- * and 2 (multiple TT mode) ... config is
- * sometimes settable
- * NOT IMPLEMENTED
- */
-
- /* one interface */
- 0x09, /* u8 if_bLength; */
- 0x04, /* u8 if_bDescriptorType; Interface */
- 0x00, /* u8 if_bInterfaceNumber; */
- 0x00, /* u8 if_bAlternateSetting; */
- 0x01, /* u8 if_bNumEndpoints; */
- 0x03, /* u8 if_bInterfaceClass; */
- 0x01, /* u8 if_bInterfaceSubClass; */
- 0x02, /* u8 if_bInterfaceProtocol; [usb1.1 or single tt] */
- 0x05, /* u8 if_iInterface; */
-
- /* HID descriptor */
- 0x09, /* u8 bLength; */
- 0x21, /* u8 bDescriptorType; */
- 0x01, 0x00, /* u16 HID_class */
- 0x00, /* u8 country_code */
- 0x01, /* u8 num_descriptors */
- 0x22, /* u8 type; Report */
- 50, 0, /* u16 len */
-
- /* one endpoint (status change endpoint) */
- 0x07, /* u8 ep_bLength; */
- 0x05, /* u8 ep_bDescriptorType; Endpoint */
- 0x81, /* u8 ep_bEndpointAddress; IN Endpoint 1 */
- 0x03, /* u8 ep_bmAttributes; Interrupt */
- 0x03, 0x00, /* u16 ep_wMaxPacketSize; */
- 0x0a, /* u8 ep_bInterval; (255ms -- usb 2.0 spec) */
-};
-
-static const uint8_t qemu_tablet_config_descriptor[] = {
- /* one configuration */
- 0x09, /* u8 bLength; */
- 0x02, /* u8 bDescriptorType; Configuration */
- 0x22, 0x00, /* u16 wTotalLength; */
- 0x01, /* u8 bNumInterfaces; (1) */
- 0x01, /* u8 bConfigurationValue; */
- 0x04, /* u8 iConfiguration; */
- 0xa0, /* u8 bmAttributes;
- Bit 7: must be set,
- 6: Self-powered,
- 5: Remote wakeup,
- 4..0: resvd */
- 50, /* u8 MaxPower; */
-
- /* USB 1.1:
- * USB 2.0, single TT organization (mandatory):
- * one interface, protocol 0
- *
- * USB 2.0, multiple TT organization (optional):
- * two interfaces, protocols 1 (like single TT)
- * and 2 (multiple TT mode) ... config is
- * sometimes settable
- * NOT IMPLEMENTED
- */
-
- /* one interface */
- 0x09, /* u8 if_bLength; */
- 0x04, /* u8 if_bDescriptorType; Interface */
- 0x00, /* u8 if_bInterfaceNumber; */
- 0x00, /* u8 if_bAlternateSetting; */
- 0x01, /* u8 if_bNumEndpoints; */
- 0x03, /* u8 if_bInterfaceClass; */
- 0x01, /* u8 if_bInterfaceSubClass; */
- 0x02, /* u8 if_bInterfaceProtocol; [usb1.1 or single tt] */
- 0x05, /* u8 if_iInterface; */
-
- /* HID descriptor */
- 0x09, /* u8 bLength; */
- 0x21, /* u8 bDescriptorType; */
- 0x01, 0x00, /* u16 HID_class */
- 0x00, /* u8 country_code */
- 0x01, /* u8 num_descriptors */
- 0x22, /* u8 type; Report */
- 74, 0, /* u16 len */
-
- /* one endpoint (status change endpoint) */
- 0x07, /* u8 ep_bLength; */
- 0x05, /* u8 ep_bDescriptorType; Endpoint */
- 0x81, /* u8 ep_bEndpointAddress; IN Endpoint 1 */
- 0x03, /* u8 ep_bmAttributes; Interrupt */
- 0x08, 0x00, /* u16 ep_wMaxPacketSize; */
- 0x03, /* u8 ep_bInterval; (255ms -- usb 2.0 spec) */
-};
-
-static const uint8_t qemu_mouse_hid_report_descriptor[] = {
- 0x05, 0x01, 0x09, 0x02, 0xA1, 0x01, 0x09, 0x01,
- 0xA1, 0x00, 0x05, 0x09, 0x19, 0x01, 0x29, 0x03,
- 0x15, 0x00, 0x25, 0x01, 0x95, 0x03, 0x75, 0x01,
- 0x81, 0x02, 0x95, 0x01, 0x75, 0x05, 0x81, 0x01,
- 0x05, 0x01, 0x09, 0x30, 0x09, 0x31, 0x15, 0x81,
- 0x25, 0x7F, 0x75, 0x08, 0x95, 0x02, 0x81, 0x06,
- 0xC0, 0xC0,
-};
-
-static const uint8_t qemu_tablet_hid_report_descriptor[] = {
- 0x05, 0x01, /* Usage Page Generic Desktop */
- 0x09, 0x01, /* Usage Mouse */
- 0xA1, 0x01, /* Collection Application */
- 0x09, 0x01, /* Usage Pointer */
- 0xA1, 0x00, /* Collection Physical */
- 0x05, 0x09, /* Usage Page Button */
- 0x19, 0x01, /* Usage Minimum Button 1 */
- 0x29, 0x03, /* Usage Maximum Button 3 */
- 0x15, 0x00, /* Logical Minimum 0 */
- 0x25, 0x01, /* Logical Maximum 1 */
- 0x95, 0x03, /* Report Count 3 */
- 0x75, 0x01, /* Report Size 1 */
- 0x81, 0x02, /* Input (Data, Var, Abs) */
- 0x95, 0x01, /* Report Count 1 */
- 0x75, 0x05, /* Report Size 5 */
- 0x81, 0x01, /* Input (Cnst, Var, Abs) */
- 0x05, 0x01, /* Usage Page Generic Desktop */
- 0x09, 0x30, /* Usage X */
- 0x09, 0x31, /* Usage Y */
- 0x15, 0x00, /* Logical Minimum 0 */
- 0x26, 0xFF, 0x7F, /* Logical Maximum 0x7fff */
- 0x35, 0x00, /* Physical Minimum 0 */
- 0x46, 0xFE, 0x7F, /* Physical Maximum 0x7fff */
- 0x75, 0x10, /* Report Size 16 */
- 0x95, 0x02, /* Report Count 2 */
- 0x81, 0x02, /* Input (Data, Var, Abs) */
- 0x05, 0x01, /* Usage Page Generic Desktop */
- 0x09, 0x38, /* Usage Wheel */
- 0x15, 0x81, /* Logical Minimum -127 */
- 0x25, 0x7F, /* Logical Maximum 127 */
- 0x35, 0x00, /* Physical Minimum 0 (same as logical) */
- 0x45, 0x00, /* Physical Maximum 0 (same as logical) */
- 0x75, 0x08, /* Report Size 8 */
- 0x95, 0x01, /* Report Count 1 */
- 0x81, 0x02, /* Input (Data, Var, Rel) */
- 0xC0, /* End Collection */
- 0xC0, /* End Collection */
-};
-
-static void usb_mouse_event(void *opaque,
- int dx1, int dy1, int dz1, int buttons_state)
-{
- USBMouseState *s = opaque;
-
- s->dx += dx1;
- s->dy += dy1;
- s->dz += dz1;
- s->buttons_state = buttons_state;
-}
-
-static void usb_tablet_event(void *opaque,
- int x, int y, int dz, int buttons_state)
-{
- USBMouseState *s = opaque;
-
- s->x = x;
- s->y = y;
- s->dz += dz;
- s->buttons_state = buttons_state;
-}
-
-static inline int int_clamp(int val, int vmin, int vmax)
-{
- if (val < vmin)
- return vmin;
- else if (val > vmax)
- return vmax;
- else
- return val;
-}
-
-static int usb_mouse_poll(USBMouseState *s, uint8_t *buf, int len)
-{
- int dx, dy, dz, b, l;
-
- if (!s->mouse_grabbed) {
- qemu_add_mouse_event_handler(usb_mouse_event, s, 0);
- s->mouse_grabbed = 1;
- }
-
- dx = int_clamp(s->dx, -128, 127);
- dy = int_clamp(s->dy, -128, 127);
- dz = int_clamp(s->dz, -128, 127);
-
- s->dx -= dx;
- s->dy -= dy;
- s->dz -= dz;
-
- b = 0;
- if (s->buttons_state & MOUSE_EVENT_LBUTTON)
- b |= 0x01;
- if (s->buttons_state & MOUSE_EVENT_RBUTTON)
- b |= 0x02;
- if (s->buttons_state & MOUSE_EVENT_MBUTTON)
- b |= 0x04;
-
- buf[0] = b;
- buf[1] = dx;
- buf[2] = dy;
- l = 3;
- if (len >= 4) {
- buf[3] = dz;
- l = 4;
- }
- return l;
-}
-
-static int usb_tablet_poll(USBMouseState *s, uint8_t *buf, int len)
-{
- int dz, b, l;
-
- if (!s->mouse_grabbed) {
- qemu_add_mouse_event_handler(usb_tablet_event, s, 1);
- s->mouse_grabbed = 1;
- }
-
- dz = int_clamp(s->dz, -128, 127);
- s->dz -= dz;
-
- /* Appears we have to invert the wheel direction */
- dz = 0 - dz;
- b = 0;
- if (s->buttons_state & MOUSE_EVENT_LBUTTON)
- b |= 0x01;
- if (s->buttons_state & MOUSE_EVENT_RBUTTON)
- b |= 0x02;
- if (s->buttons_state & MOUSE_EVENT_MBUTTON)
- b |= 0x04;
-
- buf[0] = b;
- buf[1] = s->x & 0xff;
- buf[2] = s->x >> 8;
- buf[3] = s->y & 0xff;
- buf[4] = s->y >> 8;
- buf[5] = dz;
- l = 6;
-
- return l;
-}
-
-static void usb_mouse_handle_reset(USBDevice *dev)
-{
- USBMouseState *s = (USBMouseState *)dev;
-
- s->dx = 0;
- s->dy = 0;
- s->dz = 0;
- s->x = 0;
- s->y = 0;
- s->buttons_state = 0;
-}
-
-static int usb_mouse_handle_control(USBDevice *dev, int request, int value,
- int index, int length, uint8_t *data)
-{
- USBMouseState *s = (USBMouseState *)dev;
- int ret = 0;
-
- switch(request) {
- case DeviceRequest | USB_REQ_GET_STATUS:
- data[0] = (1 << USB_DEVICE_SELF_POWERED) |
- (dev->remote_wakeup << USB_DEVICE_REMOTE_WAKEUP);
- data[1] = 0x00;
- ret = 2;
- break;
- case DeviceOutRequest | USB_REQ_CLEAR_FEATURE:
- if (value == USB_DEVICE_REMOTE_WAKEUP) {
- dev->remote_wakeup = 0;
- } else {
- goto fail;
- }
- ret = 0;
- break;
- case DeviceOutRequest | USB_REQ_SET_FEATURE:
- if (value == USB_DEVICE_REMOTE_WAKEUP) {
- dev->remote_wakeup = 1;
- } else {
- goto fail;
- }
- ret = 0;
- break;
- case DeviceOutRequest | USB_REQ_SET_ADDRESS:
- dev->addr = value;
- ret = 0;
- break;
- case DeviceRequest | USB_REQ_GET_DESCRIPTOR:
- switch(value >> 8) {
- case USB_DT_DEVICE:
- memcpy(data, qemu_mouse_dev_descriptor,
- sizeof(qemu_mouse_dev_descriptor));
- ret = sizeof(qemu_mouse_dev_descriptor);
- break;
- case USB_DT_CONFIG:
- if (s->kind == USB_MOUSE) {
- memcpy(data, qemu_mouse_config_descriptor,
- sizeof(qemu_mouse_config_descriptor));
- ret = sizeof(qemu_mouse_config_descriptor);
- } else if (s->kind == USB_TABLET) {
- memcpy(data, qemu_tablet_config_descriptor,
- sizeof(qemu_tablet_config_descriptor));
- ret = sizeof(qemu_tablet_config_descriptor);
- }
- break;
- case USB_DT_STRING:
- switch(value & 0xff) {
- case 0:
- /* language ids */
- data[0] = 4;
- data[1] = 3;
- data[2] = 0x09;
- data[3] = 0x04;
- ret = 4;
- break;
- case 1:
- /* serial number */
- ret = set_usb_string(data, "1");
- break;
- case 2:
- /* product description */
- if (s->kind == USB_MOUSE)
- ret = set_usb_string(data, "QEMU USB Mouse");
- else if (s->kind == USB_TABLET)
- ret = set_usb_string(data, "QEMU USB Tablet");
- break;
- case 3:
- /* vendor description */
- ret = set_usb_string(data, "QEMU " QEMU_VERSION);
- break;
- case 4:
- ret = set_usb_string(data, "HID Mouse");
- break;
- case 5:
- ret = set_usb_string(data, "Endpoint1 Interrupt Pipe");
- break;
- default:
- goto fail;
- }
- break;
- default:
- goto fail;
- }
- break;
- case DeviceRequest | USB_REQ_GET_CONFIGURATION:
- data[0] = 1;
- ret = 1;
- break;
- case DeviceOutRequest | USB_REQ_SET_CONFIGURATION:
- ret = 0;
- break;
- case DeviceRequest | USB_REQ_GET_INTERFACE:
- data[0] = 0;
- ret = 1;
- break;
- case DeviceOutRequest | USB_REQ_SET_INTERFACE:
- ret = 0;
- break;
- /* hid specific requests */
- case InterfaceRequest | USB_REQ_GET_DESCRIPTOR:
- switch(value >> 8) {
- case 0x22:
- if (s->kind == USB_MOUSE) {
- memcpy(data, qemu_mouse_hid_report_descriptor,
- sizeof(qemu_mouse_hid_report_descriptor));
- ret = sizeof(qemu_mouse_hid_report_descriptor);
- } else if (s->kind == USB_TABLET) {
- memcpy(data, qemu_tablet_hid_report_descriptor,
- sizeof(qemu_tablet_hid_report_descriptor));
- ret = sizeof(qemu_tablet_hid_report_descriptor);
- }
- break;
- default:
- goto fail;
- }
- break;
- case GET_REPORT:
- if (s->kind == USB_MOUSE)
- ret = usb_mouse_poll(s, data, length);
- else if (s->kind == USB_TABLET)
- ret = usb_tablet_poll(s, data, length);
- break;
- case SET_IDLE:
- ret = 0;
- break;
- default:
- fail:
- ret = USB_RET_STALL;
- break;
- }
- return ret;
-}
-
-static int usb_mouse_handle_data(USBDevice *dev, int pid,
- uint8_t devep, uint8_t *data, int len)
-{
- USBMouseState *s = (USBMouseState *)dev;
- int ret = 0;
-
- switch(pid) {
- case USB_TOKEN_IN:
- if (devep == 1) {
- if (s->kind == USB_MOUSE)
- ret = usb_mouse_poll(s, data, len);
- else if (s->kind == USB_TABLET)
- ret = usb_tablet_poll(s, data, len);
- } else {
- goto fail;
- }
- break;
- case USB_TOKEN_OUT:
- default:
- fail:
- ret = USB_RET_STALL;
- break;
- }
- return ret;
-}
-
-USBDevice *usb_tablet_init(void)
-{
- USBMouseState *s;
-
- s = qemu_mallocz(sizeof(USBMouseState));
- if (!s)
- return NULL;
- s->dev.speed = USB_SPEED_FULL;
- s->dev.handle_packet = usb_generic_handle_packet;
-
- s->dev.handle_reset = usb_mouse_handle_reset;
- s->dev.handle_control = usb_mouse_handle_control;
- s->dev.handle_data = usb_mouse_handle_data;
- s->kind = USB_TABLET;
-
- return (USBDevice *)s;
-}
-
-USBDevice *usb_mouse_init(void)
-{
- USBMouseState *s;
-
- s = qemu_mallocz(sizeof(USBMouseState));
- if (!s)
- return NULL;
- s->dev.speed = USB_SPEED_FULL;
- s->dev.handle_packet = usb_generic_handle_packet;
-
- s->dev.handle_reset = usb_mouse_handle_reset;
- s->dev.handle_control = usb_mouse_handle_control;
- s->dev.handle_data = usb_mouse_handle_data;
- s->kind = USB_MOUSE;
-
- return (USBDevice *)s;
-}
+++ /dev/null
-/*
- * QEMU USB HUB emulation
- *
- * Copyright (c) 2005 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "vl.h"
-
-//#define DEBUG
-
-#define MAX_PORTS 8
-
-typedef struct USBHubPort {
- USBPort port;
- uint16_t wPortStatus;
- uint16_t wPortChange;
-} USBHubPort;
-
-typedef struct USBHubState {
- USBDevice dev;
- int nb_ports;
- USBHubPort ports[MAX_PORTS];
-} USBHubState;
-
-#define ClearHubFeature (0x2000 | USB_REQ_CLEAR_FEATURE)
-#define ClearPortFeature (0x2300 | USB_REQ_CLEAR_FEATURE)
-#define GetHubDescriptor (0xa000 | USB_REQ_GET_DESCRIPTOR)
-#define GetHubStatus (0xa000 | USB_REQ_GET_STATUS)
-#define GetPortStatus (0xa300 | USB_REQ_GET_STATUS)
-#define SetHubFeature (0x2000 | USB_REQ_SET_FEATURE)
-#define SetPortFeature (0x2300 | USB_REQ_SET_FEATURE)
-
-#define PORT_STAT_CONNECTION 0x0001
-#define PORT_STAT_ENABLE 0x0002
-#define PORT_STAT_SUSPEND 0x0004
-#define PORT_STAT_OVERCURRENT 0x0008
-#define PORT_STAT_RESET 0x0010
-#define PORT_STAT_POWER 0x0100
-#define PORT_STAT_LOW_SPEED 0x0200
-#define PORT_STAT_HIGH_SPEED 0x0400
-#define PORT_STAT_TEST 0x0800
-#define PORT_STAT_INDICATOR 0x1000
-
-#define PORT_STAT_C_CONNECTION 0x0001
-#define PORT_STAT_C_ENABLE 0x0002
-#define PORT_STAT_C_SUSPEND 0x0004
-#define PORT_STAT_C_OVERCURRENT 0x0008
-#define PORT_STAT_C_RESET 0x0010
-
-#define PORT_CONNECTION 0
-#define PORT_ENABLE 1
-#define PORT_SUSPEND 2
-#define PORT_OVERCURRENT 3
-#define PORT_RESET 4
-#define PORT_POWER 8
-#define PORT_LOWSPEED 9
-#define PORT_HIGHSPEED 10
-#define PORT_C_CONNECTION 16
-#define PORT_C_ENABLE 17
-#define PORT_C_SUSPEND 18
-#define PORT_C_OVERCURRENT 19
-#define PORT_C_RESET 20
-#define PORT_TEST 21
-#define PORT_INDICATOR 22
-
-/* same as Linux kernel root hubs */
-
-static const uint8_t qemu_hub_dev_descriptor[] = {
- 0x12, /* u8 bLength; */
- 0x01, /* u8 bDescriptorType; Device */
- 0x10, 0x01, /* u16 bcdUSB; v1.1 */
-
- 0x09, /* u8 bDeviceClass; HUB_CLASSCODE */
- 0x00, /* u8 bDeviceSubClass; */
- 0x00, /* u8 bDeviceProtocol; [ low/full speeds only ] */
- 0x08, /* u8 bMaxPacketSize0; 8 Bytes */
-
- 0x00, 0x00, /* u16 idVendor; */
- 0x00, 0x00, /* u16 idProduct; */
- 0x01, 0x01, /* u16 bcdDevice */
-
- 0x03, /* u8 iManufacturer; */
- 0x02, /* u8 iProduct; */
- 0x01, /* u8 iSerialNumber; */
- 0x01 /* u8 bNumConfigurations; */
-};
-
-/* XXX: patch interrupt size */
-static const uint8_t qemu_hub_config_descriptor[] = {
-
- /* one configuration */
- 0x09, /* u8 bLength; */
- 0x02, /* u8 bDescriptorType; Configuration */
- 0x19, 0x00, /* u16 wTotalLength; */
- 0x01, /* u8 bNumInterfaces; (1) */
- 0x01, /* u8 bConfigurationValue; */
- 0x00, /* u8 iConfiguration; */
- 0xc0, /* u8 bmAttributes;
- Bit 7: must be set,
- 6: Self-powered,
- 5: Remote wakeup,
- 4..0: resvd */
- 0x00, /* u8 MaxPower; */
-
- /* USB 1.1:
- * USB 2.0, single TT organization (mandatory):
- * one interface, protocol 0
- *
- * USB 2.0, multiple TT organization (optional):
- * two interfaces, protocols 1 (like single TT)
- * and 2 (multiple TT mode) ... config is
- * sometimes settable
- * NOT IMPLEMENTED
- */
-
- /* one interface */
- 0x09, /* u8 if_bLength; */
- 0x04, /* u8 if_bDescriptorType; Interface */
- 0x00, /* u8 if_bInterfaceNumber; */
- 0x00, /* u8 if_bAlternateSetting; */
- 0x01, /* u8 if_bNumEndpoints; */
- 0x09, /* u8 if_bInterfaceClass; HUB_CLASSCODE */
- 0x00, /* u8 if_bInterfaceSubClass; */
- 0x00, /* u8 if_bInterfaceProtocol; [usb1.1 or single tt] */
- 0x00, /* u8 if_iInterface; */
-
- /* one endpoint (status change endpoint) */
- 0x07, /* u8 ep_bLength; */
- 0x05, /* u8 ep_bDescriptorType; Endpoint */
- 0x81, /* u8 ep_bEndpointAddress; IN Endpoint 1 */
- 0x03, /* u8 ep_bmAttributes; Interrupt */
- 0x02, 0x00, /* u16 ep_wMaxPacketSize; 1 + (MAX_ROOT_PORTS / 8) */
- 0xff /* u8 ep_bInterval; (255ms -- usb 2.0 spec) */
-};
-
-static const uint8_t qemu_hub_hub_descriptor[] =
-{
- 0x09, /* u8 bLength; */
- 0x29, /* u8 bDescriptorType; Hub-descriptor */
- 0x00, /* u8 bNbrPorts; (patched later) */
- 0x0a, /* u16 wHubCharacteristics; */
- 0x00, /* (per-port OC, no power switching) */
- 0x01, /* u8 bPwrOn2pwrGood; 2ms */
- 0x00 /* u8 bHubContrCurrent; 0 mA */
-
- /* DeviceRemovable and PortPwrCtrlMask patched in later */
-};
-
-static void usb_hub_attach(USBPort *port1, USBDevice *dev)
-{
- USBHubState *s = port1->opaque;
- USBHubPort *port = &s->ports[port1->index];
-
- if (dev) {
- if (port->port.dev)
- usb_attach(port1, NULL);
-
- port->wPortStatus |= PORT_STAT_CONNECTION;
- port->wPortChange |= PORT_STAT_C_CONNECTION;
- if (dev->speed == USB_SPEED_LOW)
- port->wPortStatus |= PORT_STAT_LOW_SPEED;
- else
- port->wPortStatus &= ~PORT_STAT_LOW_SPEED;
- port->port.dev = dev;
- } else {
- dev = port->port.dev;
- if (dev) {
- port->wPortStatus &= ~PORT_STAT_CONNECTION;
- port->wPortChange |= PORT_STAT_C_CONNECTION;
- if (port->wPortStatus & PORT_STAT_ENABLE) {
- port->wPortStatus &= ~PORT_STAT_ENABLE;
- port->wPortChange |= PORT_STAT_C_ENABLE;
- }
- port->port.dev = NULL;
- }
- }
-}
-
-static void usb_hub_handle_reset(USBDevice *dev)
-{
- /* XXX: do it */
-}
-
-static int usb_hub_handle_control(USBDevice *dev, int request, int value,
- int index, int length, uint8_t *data)
-{
- USBHubState *s = (USBHubState *)dev;
- int ret;
-
- switch(request) {
- case DeviceRequest | USB_REQ_GET_STATUS:
- data[0] = (1 << USB_DEVICE_SELF_POWERED) |
- (dev->remote_wakeup << USB_DEVICE_REMOTE_WAKEUP);
- data[1] = 0x00;
- ret = 2;
- break;
- case DeviceOutRequest | USB_REQ_CLEAR_FEATURE:
- if (value == USB_DEVICE_REMOTE_WAKEUP) {
- dev->remote_wakeup = 0;
- } else {
- goto fail;
- }
- ret = 0;
- break;
- case EndpointOutRequest | USB_REQ_CLEAR_FEATURE:
- if (value == 0 && index != 0x81) { /* clear ep halt */
- goto fail;
- }
- ret = 0;
- break;
- case DeviceOutRequest | USB_REQ_SET_FEATURE:
- if (value == USB_DEVICE_REMOTE_WAKEUP) {
- dev->remote_wakeup = 1;
- } else {
- goto fail;
- }
- ret = 0;
- break;
- case DeviceOutRequest | USB_REQ_SET_ADDRESS:
- dev->addr = value;
- ret = 0;
- break;
- case DeviceRequest | USB_REQ_GET_DESCRIPTOR:
- switch(value >> 8) {
- case USB_DT_DEVICE:
- memcpy(data, qemu_hub_dev_descriptor,
- sizeof(qemu_hub_dev_descriptor));
- ret = sizeof(qemu_hub_dev_descriptor);
- break;
- case USB_DT_CONFIG:
- memcpy(data, qemu_hub_config_descriptor,
- sizeof(qemu_hub_config_descriptor));
-
- /* status change endpoint size based on number
- * of ports */
- data[22] = (s->nb_ports + 1 + 7) / 8;
-
- ret = sizeof(qemu_hub_config_descriptor);
- break;
- case USB_DT_STRING:
- switch(value & 0xff) {
- case 0:
- /* language ids */
- data[0] = 4;
- data[1] = 3;
- data[2] = 0x09;
- data[3] = 0x04;
- ret = 4;
- break;
- case 1:
- /* serial number */
- ret = set_usb_string(data, "314159");
- break;
- case 2:
- /* product description */
- ret = set_usb_string(data, "QEMU USB Hub");
- break;
- case 3:
- /* vendor description */
- ret = set_usb_string(data, "QEMU " QEMU_VERSION);
- break;
- default:
- goto fail;
- }
- break;
- default:
- goto fail;
- }
- break;
- case DeviceRequest | USB_REQ_GET_CONFIGURATION:
- data[0] = 1;
- ret = 1;
- break;
- case DeviceOutRequest | USB_REQ_SET_CONFIGURATION:
- ret = 0;
- break;
- case DeviceRequest | USB_REQ_GET_INTERFACE:
- data[0] = 0;
- ret = 1;
- break;
- case DeviceOutRequest | USB_REQ_SET_INTERFACE:
- ret = 0;
- break;
- /* usb specific requests */
- case GetHubStatus:
- data[0] = 0;
- data[1] = 0;
- data[2] = 0;
- data[3] = 0;
- ret = 4;
- break;
- case GetPortStatus:
- {
- unsigned int n = index - 1;
- USBHubPort *port;
- if (n >= s->nb_ports)
- goto fail;
- port = &s->ports[n];
- data[0] = port->wPortStatus;
- data[1] = port->wPortStatus >> 8;
- data[2] = port->wPortChange;
- data[3] = port->wPortChange >> 8;
- ret = 4;
- }
- break;
- case SetHubFeature:
- case ClearHubFeature:
- if (value == 0 || value == 1) {
- } else {
- goto fail;
- }
- ret = 0;
- break;
- case SetPortFeature:
- {
- unsigned int n = index - 1;
- USBHubPort *port;
- USBDevice *dev;
- if (n >= s->nb_ports)
- goto fail;
- port = &s->ports[n];
- dev = port->port.dev;
- switch(value) {
- case PORT_SUSPEND:
- port->wPortStatus |= PORT_STAT_SUSPEND;
- break;
- case PORT_RESET:
- if (dev) {
- dev->handle_packet(dev,
- USB_MSG_RESET, 0, 0, NULL, 0);
- port->wPortChange |= PORT_STAT_C_RESET;
- /* set enable bit */
- port->wPortStatus |= PORT_STAT_ENABLE;
- }
- break;
- case PORT_POWER:
- break;
- default:
- goto fail;
- }
- ret = 0;
- }
- break;
- case ClearPortFeature:
- {
- unsigned int n = index - 1;
- USBHubPort *port;
- USBDevice *dev;
- if (n >= s->nb_ports)
- goto fail;
- port = &s->ports[n];
- dev = port->port.dev;
- switch(value) {
- case PORT_ENABLE:
- port->wPortStatus &= ~PORT_STAT_ENABLE;
- break;
- case PORT_C_ENABLE:
- port->wPortChange &= ~PORT_STAT_C_ENABLE;
- break;
- case PORT_SUSPEND:
- port->wPortStatus &= ~PORT_STAT_SUSPEND;
- break;
- case PORT_C_SUSPEND:
- port->wPortChange &= ~PORT_STAT_C_SUSPEND;
- break;
- case PORT_C_CONNECTION:
- port->wPortChange &= ~PORT_STAT_C_CONNECTION;
- break;
- case PORT_C_OVERCURRENT:
- port->wPortChange &= ~PORT_STAT_C_OVERCURRENT;
- break;
- case PORT_C_RESET:
- port->wPortChange &= ~PORT_STAT_C_RESET;
- break;
- default:
- goto fail;
- }
- ret = 0;
- }
- break;
- case GetHubDescriptor:
- {
- unsigned int n, limit, var_hub_size = 0;
- memcpy(data, qemu_hub_hub_descriptor,
- sizeof(qemu_hub_hub_descriptor));
- data[2] = s->nb_ports;
-
- /* fill DeviceRemovable bits */
- limit = ((s->nb_ports + 1 + 7) / 8) + 7;
- for (n = 7; n < limit; n++) {
- data[n] = 0x00;
- var_hub_size++;
- }
-
- /* fill PortPwrCtrlMask bits */
- limit = limit + ((s->nb_ports + 7) / 8);
- for (;n < limit; n++) {
- data[n] = 0xff;
- var_hub_size++;
- }
-
- ret = sizeof(qemu_hub_hub_descriptor) + var_hub_size;
- break;
- }
- default:
- fail:
- ret = USB_RET_STALL;
- break;
- }
- return ret;
-}
-
-static int usb_hub_handle_data(USBDevice *dev, int pid,
- uint8_t devep, uint8_t *data, int len)
-{
- USBHubState *s = (USBHubState *)dev;
- int ret;
-
- switch(pid) {
- case USB_TOKEN_IN:
- if (devep == 1) {
- USBHubPort *port;
- unsigned int status;
- int i, n;
- n = (s->nb_ports + 1 + 7) / 8;
- if (len == 1) { /* FreeBSD workaround */
- n = 1;
- } else if (n > len) {
- return USB_RET_BABBLE;
- }
- status = 0;
- for(i = 0; i < s->nb_ports; i++) {
- port = &s->ports[i];
- if (port->wPortChange)
- status |= (1 << (i + 1));
- }
- if (status != 0) {
- for(i = 0; i < n; i++) {
- data[i] = status >> (8 * i);
- }
- ret = n;
- } else {
- ret = USB_RET_NAK; /* usb11 11.13.1 */
- }
- } else {
- goto fail;
- }
- break;
- case USB_TOKEN_OUT:
- default:
- fail:
- ret = USB_RET_STALL;
- break;
- }
- return ret;
-}
-
-static int usb_hub_broadcast_packet(USBHubState *s, int pid,
- uint8_t devaddr, uint8_t devep,
- uint8_t *data, int len)
-{
- USBHubPort *port;
- USBDevice *dev;
- int i, ret;
-
- for(i = 0; i < s->nb_ports; i++) {
- port = &s->ports[i];
- dev = port->port.dev;
- if (dev && (port->wPortStatus & PORT_STAT_ENABLE)) {
- ret = dev->handle_packet(dev, pid,
- devaddr, devep,
- data, len);
- if (ret != USB_RET_NODEV) {
- return ret;
- }
- }
- }
- return USB_RET_NODEV;
-}
-
-static int usb_hub_handle_packet(USBDevice *dev, int pid,
- uint8_t devaddr, uint8_t devep,
- uint8_t *data, int len)
-{
- USBHubState *s = (USBHubState *)dev;
-
-#if defined(DEBUG) && 0
- printf("usb_hub: pid=0x%x\n", pid);
-#endif
- if (dev->state == USB_STATE_DEFAULT &&
- dev->addr != 0 &&
- devaddr != dev->addr &&
- (pid == USB_TOKEN_SETUP ||
- pid == USB_TOKEN_OUT ||
- pid == USB_TOKEN_IN)) {
- /* broadcast the packet to the devices */
- return usb_hub_broadcast_packet(s, pid, devaddr, devep, data, len);
- }
- return usb_generic_handle_packet(dev, pid, devaddr, devep, data, len);
-}
-
-USBDevice *usb_hub_init(USBPort **usb_ports, int nb_ports)
-{
- USBHubState *s;
- USBHubPort *port;
- int i;
-
- if (nb_ports > MAX_PORTS)
- return NULL;
- s = qemu_mallocz(sizeof(USBHubState));
- if (!s)
- return NULL;
- s->dev.speed = USB_SPEED_FULL;
- s->dev.handle_packet = usb_hub_handle_packet;
-
- /* generic USB device init */
- s->dev.handle_reset = usb_hub_handle_reset;
- s->dev.handle_control = usb_hub_handle_control;
- s->dev.handle_data = usb_hub_handle_data;
-
- s->nb_ports = nb_ports;
- for(i = 0; i < s->nb_ports; i++) {
- port = &s->ports[i];
- port->wPortStatus = PORT_STAT_POWER;
- port->wPortChange = 0;
- port->port.attach = usb_hub_attach;
- port->port.opaque = s;
- port->port.index = i;
- usb_ports[i] = &port->port;
- }
- return (USBDevice *)s;
-}
+++ /dev/null
-/*
- * USB UHCI controller emulation
- *
- * Copyright (c) 2005 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "vl.h"
-
-//#define DEBUG
-//#define DEBUG_PACKET
-
-#define UHCI_CMD_GRESET (1 << 2)
-#define UHCI_CMD_HCRESET (1 << 1)
-#define UHCI_CMD_RS (1 << 0)
-
-#define UHCI_STS_HCHALTED (1 << 5)
-#define UHCI_STS_HCPERR (1 << 4)
-#define UHCI_STS_HSERR (1 << 3)
-#define UHCI_STS_RD (1 << 2)
-#define UHCI_STS_USBERR (1 << 1)
-#define UHCI_STS_USBINT (1 << 0)
-
-#define TD_CTRL_SPD (1 << 29)
-#define TD_CTRL_ERROR_SHIFT 27
-#define TD_CTRL_IOS (1 << 25)
-#define TD_CTRL_IOC (1 << 24)
-#define TD_CTRL_ACTIVE (1 << 23)
-#define TD_CTRL_STALL (1 << 22)
-#define TD_CTRL_BABBLE (1 << 20)
-#define TD_CTRL_NAK (1 << 19)
-#define TD_CTRL_TIMEOUT (1 << 18)
-
-#define UHCI_PORT_RESET (1 << 9)
-#define UHCI_PORT_LSDA (1 << 8)
-#define UHCI_PORT_ENC (1 << 3)
-#define UHCI_PORT_EN (1 << 2)
-#define UHCI_PORT_CSC (1 << 1)
-#define UHCI_PORT_CCS (1 << 0)
-
-#define FRAME_TIMER_FREQ 1000
-
-#define FRAME_MAX_LOOPS 100
-
-#define NB_PORTS 2
-
-typedef struct UHCIPort {
- USBPort port;
- uint16_t ctrl;
-} UHCIPort;
-
-typedef struct UHCIState {
- PCIDevice dev;
- uint16_t cmd; /* cmd register */
- uint16_t status;
- uint16_t intr; /* interrupt enable register */
- uint16_t frnum; /* frame number */
- uint32_t fl_base_addr; /* frame list base address */
- uint8_t sof_timing;
- uint8_t status2; /* bit 0 and 1 are used to generate UHCI_STS_USBINT */
- QEMUTimer *frame_timer;
- UHCIPort ports[NB_PORTS];
-} UHCIState;
-
-typedef struct UHCI_TD {
- uint32_t link;
- uint32_t ctrl; /* see TD_CTRL_xxx */
- uint32_t token;
- uint32_t buffer;
-} UHCI_TD;
-
-typedef struct UHCI_QH {
- uint32_t link;
- uint32_t el_link;
-} UHCI_QH;
-
-static void uhci_attach(USBPort *port1, USBDevice *dev);
-
-static void uhci_update_irq(UHCIState *s)
-{
- int level;
- if (((s->status2 & 1) && (s->intr & (1 << 2))) ||
- ((s->status2 & 2) && (s->intr & (1 << 3))) ||
- ((s->status & UHCI_STS_USBERR) && (s->intr & (1 << 0))) ||
- ((s->status & UHCI_STS_RD) && (s->intr & (1 << 1))) ||
- (s->status & UHCI_STS_HSERR) ||
- (s->status & UHCI_STS_HCPERR)) {
- level = 1;
- } else {
- level = 0;
- }
- pci_set_irq(&s->dev, 3, level);
-}
-
-static void uhci_reset(UHCIState *s)
-{
- uint8_t *pci_conf;
- int i;
- UHCIPort *port;
-
- pci_conf = s->dev.config;
-
- pci_conf[0x6a] = 0x01; /* usb clock */
- pci_conf[0x6b] = 0x00;
- s->cmd = 0;
- s->status = 0;
- s->status2 = 0;
- s->intr = 0;
- s->fl_base_addr = 0;
- s->sof_timing = 64;
- for(i = 0; i < NB_PORTS; i++) {
- port = &s->ports[i];
- port->ctrl = 0x0080;
- if (port->port.dev)
- uhci_attach(&port->port, port->port.dev);
- }
-}
-
-static void uhci_ioport_writeb(void *opaque, uint32_t addr, uint32_t val)
-{
- UHCIState *s = opaque;
-
- addr &= 0x1f;
- switch(addr) {
- case 0x0c:
- s->sof_timing = val;
- break;
- }
-}
-
-static uint32_t uhci_ioport_readb(void *opaque, uint32_t addr)
-{
- UHCIState *s = opaque;
- uint32_t val;
-
- addr &= 0x1f;
- switch(addr) {
- case 0x0c:
- val = s->sof_timing;
- break;
- default:
- val = 0xff;
- break;
- }
- return val;
-}
-
-static void uhci_ioport_writew(void *opaque, uint32_t addr, uint32_t val)
-{
- UHCIState *s = opaque;
-
- addr &= 0x1f;
-#ifdef DEBUG
- printf("uhci writew port=0x%04x val=0x%04x\n", addr, val);
-#endif
- switch(addr) {
- case 0x00:
- if ((val & UHCI_CMD_RS) && !(s->cmd & UHCI_CMD_RS)) {
- /* start frame processing */
- qemu_mod_timer(s->frame_timer, qemu_get_clock(vm_clock));
- s->status &= ~UHCI_STS_HCHALTED;
- } else if (!(val & UHCI_CMD_RS)) {
- s->status |= UHCI_STS_HCHALTED;
- }
- if (val & UHCI_CMD_GRESET) {
- UHCIPort *port;
- USBDevice *dev;
- int i;
-
- /* send reset on the USB bus */
- for(i = 0; i < NB_PORTS; i++) {
- port = &s->ports[i];
- dev = port->port.dev;
- if (dev) {
- dev->handle_packet(dev,
- USB_MSG_RESET, 0, 0, NULL, 0);
- }
- }
- uhci_reset(s);
- return;
- }
- if (val & UHCI_CMD_HCRESET) {
- uhci_reset(s);
- return;
- }
- s->cmd = val;
- break;
- case 0x02:
- s->status &= ~val;
- /* XXX: the chip spec is not coherent, so we add a hidden
- register to distinguish between IOC and SPD */
- if (val & UHCI_STS_USBINT)
- s->status2 = 0;
- uhci_update_irq(s);
- break;
- case 0x04:
- s->intr = val;
- uhci_update_irq(s);
- break;
- case 0x06:
- if (s->status & UHCI_STS_HCHALTED)
- s->frnum = val & 0x7ff;
- break;
- case 0x10 ... 0x1f:
- {
- UHCIPort *port;
- USBDevice *dev;
- int n;
-
- n = (addr >> 1) & 7;
- if (n >= NB_PORTS)
- return;
- port = &s->ports[n];
- dev = port->port.dev;
- if (dev) {
- /* port reset */
- if ( (val & UHCI_PORT_RESET) &&
- !(port->ctrl & UHCI_PORT_RESET) ) {
- dev->handle_packet(dev,
- USB_MSG_RESET, 0, 0, NULL, 0);
- }
- }
- port->ctrl = (port->ctrl & 0x01fb) | (val & ~0x01fb);
- /* some bits are reset when a '1' is written to them */
- port->ctrl &= ~(val & 0x000a);
- }
- break;
- }
-}
-
-static uint32_t uhci_ioport_readw(void *opaque, uint32_t addr)
-{
- UHCIState *s = opaque;
- uint32_t val;
-
- addr &= 0x1f;
- switch(addr) {
- case 0x00:
- val = s->cmd;
- break;
- case 0x02:
- val = s->status;
- break;
- case 0x04:
- val = s->intr;
- break;
- case 0x06:
- val = s->frnum;
- break;
- case 0x10 ... 0x1f:
- {
- UHCIPort *port;
- int n;
- n = (addr >> 1) & 7;
- if (n >= NB_PORTS)
- goto read_default;
- port = &s->ports[n];
- val = port->ctrl;
- }
- break;
- default:
- read_default:
- val = 0xff7f; /* disabled port */
- break;
- }
-#ifdef DEBUG
- printf("uhci readw port=0x%04x val=0x%04x\n", addr, val);
-#endif
- return val;
-}
-
-static void uhci_ioport_writel(void *opaque, uint32_t addr, uint32_t val)
-{
- UHCIState *s = opaque;
-
- addr &= 0x1f;
-#ifdef DEBUG
- printf("uhci writel port=0x%04x val=0x%08x\n", addr, val);
-#endif
- switch(addr) {
- case 0x08:
- s->fl_base_addr = val & ~0xfff;
- break;
- }
-}
-
-static uint32_t uhci_ioport_readl(void *opaque, uint32_t addr)
-{
- UHCIState *s = opaque;
- uint32_t val;
-
- addr &= 0x1f;
- switch(addr) {
- case 0x08:
- val = s->fl_base_addr;
- break;
- default:
- val = 0xffffffff;
- break;
- }
- return val;
-}
-
-static void uhci_attach(USBPort *port1, USBDevice *dev)
-{
- UHCIState *s = port1->opaque;
- UHCIPort *port = &s->ports[port1->index];
-
- if (dev) {
- if (port->port.dev) {
- usb_attach(port1, NULL);
- }
- /* set connect status */
- if (!(port->ctrl & UHCI_PORT_CCS)) {
- port->ctrl |= UHCI_PORT_CCS | UHCI_PORT_CSC;
- }
- /* update speed */
- if (dev->speed == USB_SPEED_LOW)
- port->ctrl |= UHCI_PORT_LSDA;
- else
- port->ctrl &= ~UHCI_PORT_LSDA;
- port->port.dev = dev;
- /* send the attach message */
- dev->handle_packet(dev,
- USB_MSG_ATTACH, 0, 0, NULL, 0);
- } else {
- /* set connect status */
- if (!(port->ctrl & UHCI_PORT_CCS)) {
- port->ctrl |= UHCI_PORT_CCS | UHCI_PORT_CSC;
- }
- /* disable port */
- if (port->ctrl & UHCI_PORT_EN) {
- port->ctrl &= ~UHCI_PORT_EN;
- port->ctrl |= UHCI_PORT_ENC;
- }
- dev = port->port.dev;
- if (dev) {
- /* send the detach message */
- dev->handle_packet(dev,
- USB_MSG_DETACH, 0, 0, NULL, 0);
- }
- port->port.dev = NULL;
- }
-}
-
-static int uhci_broadcast_packet(UHCIState *s, uint8_t pid,
- uint8_t devaddr, uint8_t devep,
- uint8_t *data, int len)
-{
- UHCIPort *port;
- USBDevice *dev;
- int i, ret;
-
-#ifdef DEBUG_PACKET
- {
- const char *pidstr;
- switch(pid) {
- case USB_TOKEN_SETUP: pidstr = "SETUP"; break;
- case USB_TOKEN_IN: pidstr = "IN"; break;
- case USB_TOKEN_OUT: pidstr = "OUT"; break;
- default: pidstr = "?"; break;
- }
- printf("frame %d: pid=%s addr=0x%02x ep=%d len=%d\n",
- s->frnum, pidstr, devaddr, devep, len);
- if (pid != USB_TOKEN_IN) {
- printf(" data_out=");
- for(i = 0; i < len; i++) {
- printf(" %02x", data[i]);
- }
- printf("\n");
- }
- }
-#endif
- for(i = 0; i < NB_PORTS; i++) {
- port = &s->ports[i];
- dev = port->port.dev;
- if (dev && (port->ctrl & UHCI_PORT_EN)) {
- ret = dev->handle_packet(dev, pid,
- devaddr, devep,
- data, len);
- if (ret != USB_RET_NODEV) {
-#ifdef DEBUG_PACKET
- {
- printf(" ret=%d ", ret);
- if (pid == USB_TOKEN_IN && ret > 0) {
- printf("data_in=");
- for(i = 0; i < ret; i++) {
- printf(" %02x", data[i]);
- }
- }
- printf("\n");
- }
-#endif
- return ret;
- }
- }
- }
- return USB_RET_NODEV;
-}
-
-/* return -1 if fatal error (frame must be stopped)
- 0 if TD successful
- 1 if TD unsuccessful or inactive
-*/
-static int uhci_handle_td(UHCIState *s, UHCI_TD *td, int *int_mask)
-{
- uint8_t pid;
- uint8_t buf[1280];
- int len, max_len, err, ret;
-
- if (td->ctrl & TD_CTRL_IOC) {
- *int_mask |= 0x01;
- }
-
- if (!(td->ctrl & TD_CTRL_ACTIVE))
- return 1;
-
- /* TD is active */
- max_len = ((td->token >> 21) + 1) & 0x7ff;
- pid = td->token & 0xff;
- switch(pid) {
- case USB_TOKEN_OUT:
- case USB_TOKEN_SETUP:
- cpu_physical_memory_read(td->buffer, buf, max_len);
- ret = uhci_broadcast_packet(s, pid,
- (td->token >> 8) & 0x7f,
- (td->token >> 15) & 0xf,
- buf, max_len);
- len = max_len;
- break;
- case USB_TOKEN_IN:
- ret = uhci_broadcast_packet(s, pid,
- (td->token >> 8) & 0x7f,
- (td->token >> 15) & 0xf,
- buf, max_len);
- if (ret >= 0) {
- len = ret;
- if (len > max_len) {
- len = max_len;
- ret = USB_RET_BABBLE;
- }
- if (len > 0) {
- /* write the data back */
- cpu_physical_memory_write(td->buffer, buf, len);
- }
- } else {
- len = 0;
- }
- break;
- default:
- /* invalid pid : frame interrupted */
- s->status |= UHCI_STS_HCPERR;
- uhci_update_irq(s);
- return -1;
- }
- if (td->ctrl & TD_CTRL_IOS)
- td->ctrl &= ~TD_CTRL_ACTIVE;
- if (ret >= 0) {
- td->ctrl = (td->ctrl & ~0x7ff) | ((len - 1) & 0x7ff);
- td->ctrl &= ~TD_CTRL_ACTIVE;
- if (pid == USB_TOKEN_IN &&
- (td->ctrl & TD_CTRL_SPD) &&
- len < max_len) {
- *int_mask |= 0x02;
- /* short packet: do not update QH */
- return 1;
- } else {
- /* success */
- return 0;
- }
- } else {
- switch(ret) {
- default:
- case USB_RET_NODEV:
- do_timeout:
- td->ctrl |= TD_CTRL_TIMEOUT;
- err = (td->ctrl >> TD_CTRL_ERROR_SHIFT) & 3;
- if (err != 0) {
- err--;
- if (err == 0) {
- td->ctrl &= ~TD_CTRL_ACTIVE;
- s->status |= UHCI_STS_USBERR;
- uhci_update_irq(s);
- }
- }
- td->ctrl = (td->ctrl & ~(3 << TD_CTRL_ERROR_SHIFT)) |
- (err << TD_CTRL_ERROR_SHIFT);
- return 1;
- case USB_RET_NAK:
- td->ctrl |= TD_CTRL_NAK;
- if (pid == USB_TOKEN_SETUP)
- goto do_timeout;
- return 1;
- case USB_RET_STALL:
- td->ctrl |= TD_CTRL_STALL;
- td->ctrl &= ~TD_CTRL_ACTIVE;
- return 1;
- case USB_RET_BABBLE:
- td->ctrl |= TD_CTRL_BABBLE | TD_CTRL_STALL;
- td->ctrl &= ~TD_CTRL_ACTIVE;
- /* frame interrupted */
- return -1;
- }
- }
-}
-
-static void uhci_frame_timer(void *opaque)
-{
- UHCIState *s = opaque;
- int64_t expire_time;
- uint32_t frame_addr, link, old_td_ctrl, val;
- int int_mask, cnt, ret;
- UHCI_TD td;
- UHCI_QH qh;
-
- if (!(s->cmd & UHCI_CMD_RS)) {
- qemu_del_timer(s->frame_timer);
- /* set hchalted bit in status - UHCI11D 2.1.2 */
- s->status |= UHCI_STS_HCHALTED;
- return;
- }
- frame_addr = s->fl_base_addr + ((s->frnum & 0x3ff) << 2);
- cpu_physical_memory_read(frame_addr, (uint8_t *)&link, 4);
- le32_to_cpus(&link);
- int_mask = 0;
- cnt = FRAME_MAX_LOOPS;
- while ((link & 1) == 0) {
- if (--cnt == 0)
- break;
- /* valid frame */
- if (link & 2) {
- /* QH */
- cpu_physical_memory_read(link & ~0xf, (uint8_t *)&qh, sizeof(qh));
- le32_to_cpus(&qh.link);
- le32_to_cpus(&qh.el_link);
- depth_first:
- if (qh.el_link & 1) {
- /* no element : go to next entry */
- link = qh.link;
- } else if (qh.el_link & 2) {
- /* QH */
- link = qh.el_link;
- } else {
- /* TD */
- if (--cnt == 0)
- break;
- cpu_physical_memory_read(qh.el_link & ~0xf,
- (uint8_t *)&td, sizeof(td));
- le32_to_cpus(&td.link);
- le32_to_cpus(&td.ctrl);
- le32_to_cpus(&td.token);
- le32_to_cpus(&td.buffer);
- old_td_ctrl = td.ctrl;
- ret = uhci_handle_td(s, &td, &int_mask);
- /* update the status bits of the TD */
- if (old_td_ctrl != td.ctrl) {
- val = cpu_to_le32(td.ctrl);
- cpu_physical_memory_write((qh.el_link & ~0xf) + 4,
- (const uint8_t *)&val,
- sizeof(val));
- }
- if (ret < 0)
- break; /* interrupted frame */
- if (ret == 0) {
- /* update qh element link */
- qh.el_link = td.link;
- val = cpu_to_le32(qh.el_link);
- cpu_physical_memory_write((link & ~0xf) + 4,
- (const uint8_t *)&val,
- sizeof(val));
- if (qh.el_link & 4) {
- /* depth first */
- goto depth_first;
- }
- }
- /* go to next entry */
- link = qh.link;
- }
- } else {
- /* TD */
- cpu_physical_memory_read(link & ~0xf, (uint8_t *)&td, sizeof(td));
- le32_to_cpus(&td.link);
- le32_to_cpus(&td.ctrl);
- le32_to_cpus(&td.token);
- le32_to_cpus(&td.buffer);
- old_td_ctrl = td.ctrl;
- ret = uhci_handle_td(s, &td, &int_mask);
- /* update the status bits of the TD */
- if (old_td_ctrl != td.ctrl) {
- val = cpu_to_le32(td.ctrl);
- cpu_physical_memory_write((link & ~0xf) + 4,
- (const uint8_t *)&val,
- sizeof(val));
- }
- if (ret < 0)
- break; /* interrupted frame */
- link = td.link;
- }
- }
- s->frnum = (s->frnum + 1) & 0x7ff;
- if (int_mask) {
- s->status2 |= int_mask;
- s->status |= UHCI_STS_USBINT;
- uhci_update_irq(s);
- }
- /* prepare the timer for the next frame */
- expire_time = qemu_get_clock(vm_clock) +
- (ticks_per_sec / FRAME_TIMER_FREQ);
- qemu_mod_timer(s->frame_timer, expire_time);
-}
-
-static void uhci_map(PCIDevice *pci_dev, int region_num,
- uint32_t addr, uint32_t size, int type)
-{
- UHCIState *s = (UHCIState *)pci_dev;
-
- register_ioport_write(addr, 32, 2, uhci_ioport_writew, s);
- register_ioport_read(addr, 32, 2, uhci_ioport_readw, s);
- register_ioport_write(addr, 32, 4, uhci_ioport_writel, s);
- register_ioport_read(addr, 32, 4, uhci_ioport_readl, s);
- register_ioport_write(addr, 32, 1, uhci_ioport_writeb, s);
- register_ioport_read(addr, 32, 1, uhci_ioport_readb, s);
-}
-
-void usb_uhci_init(PCIBus *bus, USBPort **usb_ports)
-{
- UHCIState *s;
- uint8_t *pci_conf;
- UHCIPort *port;
- int i;
-
- s = (UHCIState *)pci_register_device(bus,
- "USB-UHCI", sizeof(UHCIState),
- ((PCIDevice *)piix3_state)->devfn + 2,
- NULL, NULL);
- pci_conf = s->dev.config;
- pci_conf[0x00] = 0x86;
- pci_conf[0x01] = 0x80;
- pci_conf[0x02] = 0x20;
- pci_conf[0x03] = 0x70;
- pci_conf[0x08] = 0x01; // revision number
- pci_conf[0x09] = 0x00;
- pci_conf[0x0a] = 0x03;
- pci_conf[0x0b] = 0x0c;
- pci_conf[0x0e] = 0x00; // header_type
- pci_conf[0x3d] = 4; // interrupt pin 3
- pci_conf[0x60] = 0x10; // release number
-
- for(i = 0; i < NB_PORTS; i++) {
- port = &s->ports[i];
- port->port.opaque = s;
- port->port.index = i;
- port->port.attach = uhci_attach;
- usb_ports[i] = &port->port;
- }
- s->frame_timer = qemu_new_timer(vm_clock, uhci_frame_timer, s);
-
- uhci_reset(s);
-
- /* Use region 4 for consistency with real hardware. BSD guests seem
- to rely on this. */
- pci_register_io_region(&s->dev, 4, 0x20,
- PCI_ADDRESS_SPACE_IO, uhci_map);
-}
+++ /dev/null
-/*
- * QEMU USB emulation
- *
- * Copyright (c) 2005 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "vl.h"
-
-void usb_attach(USBPort *port, USBDevice *dev)
-{
- port->attach(port, dev);
-}
-
-/**********************/
-/* generic USB device helpers (you are not forced to use them when
- writing your USB device driver, but they help handling the
- protocol)
-*/
-
-#define SETUP_STATE_IDLE 0
-#define SETUP_STATE_DATA 1
-#define SETUP_STATE_ACK 2
-
-int usb_generic_handle_packet(USBDevice *s, int pid,
- uint8_t devaddr, uint8_t devep,
- uint8_t *data, int len)
-{
- int l, ret = 0;
-
- switch(pid) {
- case USB_MSG_ATTACH:
- s->state = USB_STATE_ATTACHED;
- break;
- case USB_MSG_DETACH:
- s->state = USB_STATE_NOTATTACHED;
- break;
- case USB_MSG_RESET:
- s->remote_wakeup = 0;
- s->addr = 0;
- s->state = USB_STATE_DEFAULT;
- s->handle_reset(s);
- break;
- case USB_TOKEN_SETUP:
- if (s->state < USB_STATE_DEFAULT || devaddr != s->addr)
- return USB_RET_NODEV;
- if (len != 8)
- goto fail;
- memcpy(s->setup_buf, data, 8);
- s->setup_len = (s->setup_buf[7] << 8) | s->setup_buf[6];
- s->setup_index = 0;
- if (s->setup_buf[0] & USB_DIR_IN) {
- ret = s->handle_control(s,
- (s->setup_buf[0] << 8) | s->setup_buf[1],
- (s->setup_buf[3] << 8) | s->setup_buf[2],
- (s->setup_buf[5] << 8) | s->setup_buf[4],
- s->setup_len,
- s->data_buf);
- if (ret < 0)
- return ret;
- if (ret < s->setup_len)
- s->setup_len = ret;
- s->setup_state = SETUP_STATE_DATA;
- } else {
- if (s->setup_len == 0)
- s->setup_state = SETUP_STATE_ACK;
- else
- s->setup_state = SETUP_STATE_DATA;
- }
- break;
- case USB_TOKEN_IN:
- if (s->state < USB_STATE_DEFAULT || devaddr != s->addr)
- return USB_RET_NODEV;
- switch(devep) {
- case 0:
- switch(s->setup_state) {
- case SETUP_STATE_ACK:
- if (!(s->setup_buf[0] & USB_DIR_IN)) {
- s->setup_state = SETUP_STATE_IDLE;
- ret = s->handle_control(s,
- (s->setup_buf[0] << 8) | s->setup_buf[1],
- (s->setup_buf[3] << 8) | s->setup_buf[2],
- (s->setup_buf[5] << 8) | s->setup_buf[4],
- s->setup_len,
- s->data_buf);
- if (ret > 0)
- ret = 0;
- } else {
- /* return 0 byte */
- }
- break;
- case SETUP_STATE_DATA:
- if (s->setup_buf[0] & USB_DIR_IN) {
- l = s->setup_len - s->setup_index;
- if (l > len)
- l = len;
- memcpy(data, s->data_buf + s->setup_index, l);
- s->setup_index += l;
- if (s->setup_index >= s->setup_len)
- s->setup_state = SETUP_STATE_ACK;
- ret = l;
- } else {
- s->setup_state = SETUP_STATE_IDLE;
- goto fail;
- }
- break;
- default:
- goto fail;
- }
- break;
- default:
- ret = s->handle_data(s, pid, devep, data, len);
- break;
- }
- break;
- case USB_TOKEN_OUT:
- if (s->state < USB_STATE_DEFAULT || devaddr != s->addr)
- return USB_RET_NODEV;
- switch(devep) {
- case 0:
- switch(s->setup_state) {
- case SETUP_STATE_ACK:
- if (s->setup_buf[0] & USB_DIR_IN) {
- s->setup_state = SETUP_STATE_IDLE;
- /* transfer OK */
- } else {
- /* ignore additionnal output */
- }
- break;
- case SETUP_STATE_DATA:
- if (!(s->setup_buf[0] & USB_DIR_IN)) {
- l = s->setup_len - s->setup_index;
- if (l > len)
- l = len;
- memcpy(s->data_buf + s->setup_index, data, l);
- s->setup_index += l;
- if (s->setup_index >= s->setup_len)
- s->setup_state = SETUP_STATE_ACK;
- ret = l;
- } else {
- s->setup_state = SETUP_STATE_IDLE;
- goto fail;
- }
- break;
- default:
- goto fail;
- }
- break;
- default:
- ret = s->handle_data(s, pid, devep, data, len);
- break;
- }
- break;
- default:
- fail:
- ret = USB_RET_STALL;
- break;
- }
- return ret;
-}
-
-/* XXX: fix overflow */
-int set_usb_string(uint8_t *buf, const char *str)
-{
- int len, i;
- uint8_t *q;
-
- q = buf;
- len = strlen(str);
- *q++ = 2 * len + 2;
- *q++ = 3;
- for(i = 0; i < len; i++) {
- *q++ = str[i];
- *q++ = 0;
- }
- return q - buf;
-}
+++ /dev/null
-/*
- * QEMU USB API
- *
- * Copyright (c) 2005 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#define USB_TOKEN_SETUP 0x2d
-#define USB_TOKEN_IN 0x69 /* device -> host */
-#define USB_TOKEN_OUT 0xe1 /* host -> device */
-
-/* specific usb messages, also sent in the 'pid' parameter */
-#define USB_MSG_ATTACH 0x100
-#define USB_MSG_DETACH 0x101
-#define USB_MSG_RESET 0x102
-
-#define USB_RET_NODEV (-1)
-#define USB_RET_NAK (-2)
-#define USB_RET_STALL (-3)
-#define USB_RET_BABBLE (-4)
-
-#define USB_SPEED_LOW 0
-#define USB_SPEED_FULL 1
-#define USB_SPEED_HIGH 2
-
-#define USB_STATE_NOTATTACHED 0
-#define USB_STATE_ATTACHED 1
-//#define USB_STATE_POWERED 2
-#define USB_STATE_DEFAULT 3
-//#define USB_STATE_ADDRESS 4
-//#define USB_STATE_CONFIGURED 5
-#define USB_STATE_SUSPENDED 6
-
-#define USB_CLASS_AUDIO 1
-#define USB_CLASS_COMM 2
-#define USB_CLASS_HID 3
-#define USB_CLASS_PHYSICAL 5
-#define USB_CLASS_STILL_IMAGE 6
-#define USB_CLASS_PRINTER 7
-#define USB_CLASS_MASS_STORAGE 8
-#define USB_CLASS_HUB 9
-#define USB_CLASS_CDC_DATA 0x0a
-#define USB_CLASS_CSCID 0x0b
-#define USB_CLASS_CONTENT_SEC 0x0d
-#define USB_CLASS_APP_SPEC 0xfe
-#define USB_CLASS_VENDOR_SPEC 0xff
-
-#define USB_DIR_OUT 0
-#define USB_DIR_IN 0x80
-
-#define USB_TYPE_MASK (0x03 << 5)
-#define USB_TYPE_STANDARD (0x00 << 5)
-#define USB_TYPE_CLASS (0x01 << 5)
-#define USB_TYPE_VENDOR (0x02 << 5)
-#define USB_TYPE_RESERVED (0x03 << 5)
-
-#define USB_RECIP_MASK 0x1f
-#define USB_RECIP_DEVICE 0x00
-#define USB_RECIP_INTERFACE 0x01
-#define USB_RECIP_ENDPOINT 0x02
-#define USB_RECIP_OTHER 0x03
-
-#define DeviceRequest ((USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_DEVICE)<<8)
-#define DeviceOutRequest ((USB_DIR_OUT|USB_TYPE_STANDARD|USB_RECIP_DEVICE)<<8)
-#define InterfaceRequest \
- ((USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_INTERFACE)<<8)
-#define InterfaceOutRequest \
- ((USB_DIR_OUT|USB_TYPE_STANDARD|USB_RECIP_INTERFACE)<<8)
-#define EndpointRequest ((USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_ENDPOINT)<<8)
-#define EndpointOutRequest \
- ((USB_DIR_OUT|USB_TYPE_STANDARD|USB_RECIP_ENDPOINT)<<8)
-
-#define USB_REQ_GET_STATUS 0x00
-#define USB_REQ_CLEAR_FEATURE 0x01
-#define USB_REQ_SET_FEATURE 0x03
-#define USB_REQ_SET_ADDRESS 0x05
-#define USB_REQ_GET_DESCRIPTOR 0x06
-#define USB_REQ_SET_DESCRIPTOR 0x07
-#define USB_REQ_GET_CONFIGURATION 0x08
-#define USB_REQ_SET_CONFIGURATION 0x09
-#define USB_REQ_GET_INTERFACE 0x0A
-#define USB_REQ_SET_INTERFACE 0x0B
-#define USB_REQ_SYNCH_FRAME 0x0C
-
-#define USB_DEVICE_SELF_POWERED 0
-#define USB_DEVICE_REMOTE_WAKEUP 1
-
-#define USB_DT_DEVICE 0x01
-#define USB_DT_CONFIG 0x02
-#define USB_DT_STRING 0x03
-#define USB_DT_INTERFACE 0x04
-#define USB_DT_ENDPOINT 0x05
-
-typedef struct USBPort USBPort;
-typedef struct USBDevice USBDevice;
-
-/* definition of a USB device */
-struct USBDevice {
- void *opaque;
- int (*handle_packet)(USBDevice *dev, int pid,
- uint8_t devaddr, uint8_t devep,
- uint8_t *data, int len);
- int speed;
-
- /* The following fields are used by the generic USB device
- layer. They are here just to avoid creating a new structure for
- them. */
- void (*handle_reset)(USBDevice *dev);
- int (*handle_control)(USBDevice *dev, int request, int value,
- int index, int length, uint8_t *data);
- int (*handle_data)(USBDevice *dev, int pid, uint8_t devep,
- uint8_t *data, int len);
- uint8_t addr;
-
- int state;
- uint8_t setup_buf[8];
- uint8_t data_buf[1024];
- int remote_wakeup;
- int setup_state;
- int setup_len;
- int setup_index;
-};
-
-/* USB port on which a device can be connected */
-struct USBPort {
- USBDevice *dev;
- void (*attach)(USBPort *port, USBDevice *dev);
- void *opaque;
- int index; /* internal port index, may be used with the opaque */
-};
-
-void usb_attach(USBPort *port, USBDevice *dev);
-int usb_generic_handle_packet(USBDevice *s, int pid,
- uint8_t devaddr, uint8_t devep,
- uint8_t *data, int len);
-int set_usb_string(uint8_t *buf, const char *str);
-
-/* usb hub */
-USBDevice *usb_hub_init(USBPort **usb_ports, int nb_ports);
-
-/* usb-uhci.c */
-void usb_uhci_init(PCIBus *bus, USBPort **usb_ports);
-
-/* usb-linux.c */
-USBDevice *usb_host_device_open(const char *devname);
-void usb_host_info(void);
-
-/* usb-hid.c */
-USBDevice *usb_mouse_init(void);
-USBDevice *usb_tablet_init(void);
+++ /dev/null
-/*
- * QEMU VGA Emulator.
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "vl.h"
-#include "vga_int.h"
-
-//#define DEBUG_VGA
-//#define DEBUG_VGA_MEM
-//#define DEBUG_VGA_REG
-
-//#define DEBUG_S3
-//#define DEBUG_BOCHS_VBE
-
-/* S3 VGA is deprecated - another graphic card will be emulated */
-//#define CONFIG_S3VGA
-
-/* force some bits to zero */
-const uint8_t sr_mask[8] = {
- (uint8_t)~0xfc,
- (uint8_t)~0xc2,
- (uint8_t)~0xf0,
- (uint8_t)~0xc0,
- (uint8_t)~0xf1,
- (uint8_t)~0xff,
- (uint8_t)~0xff,
- (uint8_t)~0x00,
-};
-
-const uint8_t gr_mask[16] = {
- (uint8_t)~0xf0, /* 0x00 */
- (uint8_t)~0xf0, /* 0x01 */
- (uint8_t)~0xf0, /* 0x02 */
- (uint8_t)~0xe0, /* 0x03 */
- (uint8_t)~0xfc, /* 0x04 */
- (uint8_t)~0x84, /* 0x05 */
- (uint8_t)~0xf0, /* 0x06 */
- (uint8_t)~0xf0, /* 0x07 */
- (uint8_t)~0x00, /* 0x08 */
- (uint8_t)~0xff, /* 0x09 */
- (uint8_t)~0xff, /* 0x0a */
- (uint8_t)~0xff, /* 0x0b */
- (uint8_t)~0xff, /* 0x0c */
- (uint8_t)~0xff, /* 0x0d */
- (uint8_t)~0xff, /* 0x0e */
- (uint8_t)~0xff, /* 0x0f */
-};
-
-#define cbswap_32(__x) \
-((uint32_t)( \
- (((uint32_t)(__x) & (uint32_t)0x000000ffUL) << 24) | \
- (((uint32_t)(__x) & (uint32_t)0x0000ff00UL) << 8) | \
- (((uint32_t)(__x) & (uint32_t)0x00ff0000UL) >> 8) | \
- (((uint32_t)(__x) & (uint32_t)0xff000000UL) >> 24) ))
-
-#ifdef WORDS_BIGENDIAN
-#define PAT(x) cbswap_32(x)
-#else
-#define PAT(x) (x)
-#endif
-
-#ifdef WORDS_BIGENDIAN
-#define BIG 1
-#else
-#define BIG 0
-#endif
-
-#ifdef WORDS_BIGENDIAN
-#define GET_PLANE(data, p) (((data) >> (24 - (p) * 8)) & 0xff)
-#else
-#define GET_PLANE(data, p) (((data) >> ((p) * 8)) & 0xff)
-#endif
-
-static const uint32_t mask16[16] = {
- PAT(0x00000000),
- PAT(0x000000ff),
- PAT(0x0000ff00),
- PAT(0x0000ffff),
- PAT(0x00ff0000),
- PAT(0x00ff00ff),
- PAT(0x00ffff00),
- PAT(0x00ffffff),
- PAT(0xff000000),
- PAT(0xff0000ff),
- PAT(0xff00ff00),
- PAT(0xff00ffff),
- PAT(0xffff0000),
- PAT(0xffff00ff),
- PAT(0xffffff00),
- PAT(0xffffffff),
-};
-
-#undef PAT
-
-#ifdef WORDS_BIGENDIAN
-#define PAT(x) (x)
-#else
-#define PAT(x) cbswap_32(x)
-#endif
-
-static const uint32_t dmask16[16] = {
- PAT(0x00000000),
- PAT(0x000000ff),
- PAT(0x0000ff00),
- PAT(0x0000ffff),
- PAT(0x00ff0000),
- PAT(0x00ff00ff),
- PAT(0x00ffff00),
- PAT(0x00ffffff),
- PAT(0xff000000),
- PAT(0xff0000ff),
- PAT(0xff00ff00),
- PAT(0xff00ffff),
- PAT(0xffff0000),
- PAT(0xffff00ff),
- PAT(0xffffff00),
- PAT(0xffffffff),
-};
-
-static const uint32_t dmask4[4] = {
- PAT(0x00000000),
- PAT(0x0000ffff),
- PAT(0xffff0000),
- PAT(0xffffffff),
-};
-
-static uint32_t expand4[256];
-static uint16_t expand2[256];
-static uint8_t expand4to8[16];
-
-VGAState *vga_state;
-int vga_io_memory;
-
-static uint32_t vga_ioport_read(void *opaque, uint32_t addr)
-{
- VGAState *s = opaque;
- int val, index;
-
- /* check port range access depending on color/monochrome mode */
- if ((addr >= 0x3b0 && addr <= 0x3bf && (s->msr & MSR_COLOR_EMULATION)) ||
- (addr >= 0x3d0 && addr <= 0x3df && !(s->msr & MSR_COLOR_EMULATION))) {
- val = 0xff;
- } else {
- switch(addr) {
- case 0x3c0:
- if (s->ar_flip_flop == 0) {
- val = s->ar_index;
- } else {
- val = 0;
- }
- break;
- case 0x3c1:
- index = s->ar_index & 0x1f;
- if (index < 21)
- val = s->ar[index];
- else
- val = 0;
- break;
- case 0x3c2:
- val = s->st00;
- break;
- case 0x3c4:
- val = s->sr_index;
- break;
- case 0x3c5:
- val = s->sr[s->sr_index];
-#ifdef DEBUG_VGA_REG
- printf("vga: read SR%x = 0x%02x\n", s->sr_index, val);
-#endif
- break;
- case 0x3c7:
- val = s->dac_state;
- break;
- case 0x3c8:
- val = s->dac_write_index;
- break;
- case 0x3c9:
- val = s->palette[s->dac_read_index * 3 + s->dac_sub_index];
- if (++s->dac_sub_index == 3) {
- s->dac_sub_index = 0;
- s->dac_read_index++;
- }
- break;
- case 0x3ca:
- val = s->fcr;
- break;
- case 0x3cc:
- val = s->msr;
- break;
- case 0x3ce:
- val = s->gr_index;
- break;
- case 0x3cf:
- val = s->gr[s->gr_index];
-#ifdef DEBUG_VGA_REG
- printf("vga: read GR%x = 0x%02x\n", s->gr_index, val);
-#endif
- break;
- case 0x3b4:
- case 0x3d4:
- val = s->cr_index;
- break;
- case 0x3b5:
- case 0x3d5:
- val = s->cr[s->cr_index];
-#ifdef DEBUG_VGA_REG
- printf("vga: read CR%x = 0x%02x\n", s->cr_index, val);
-#endif
-#ifdef DEBUG_S3
- if (s->cr_index >= 0x20)
- printf("S3: CR read index=0x%x val=0x%x\n",
- s->cr_index, val);
-#endif
- break;
- case 0x3ba:
- case 0x3da:
- /* just toggle to fool polling */
- s->st01 ^= ST01_V_RETRACE | ST01_DISP_ENABLE;
- val = s->st01;
- s->ar_flip_flop = 0;
- break;
- default:
- val = 0x00;
- break;
- }
- }
-#if defined(DEBUG_VGA)
- printf("VGA: read addr=0x%04x data=0x%02x\n", addr, val);
-#endif
- return val;
-}
-
-static void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val)
-{
- VGAState *s = opaque;
- int index;
-
- /* check port range access depending on color/monochrome mode */
- if ((addr >= 0x3b0 && addr <= 0x3bf && (s->msr & MSR_COLOR_EMULATION)) ||
- (addr >= 0x3d0 && addr <= 0x3df && !(s->msr & MSR_COLOR_EMULATION)))
- return;
-
-#ifdef DEBUG_VGA
- printf("VGA: write addr=0x%04x data=0x%02x\n", addr, val);
-#endif
-
- switch(addr) {
- case 0x3c0:
- if (s->ar_flip_flop == 0) {
- val &= 0x3f;
- s->ar_index = val;
- } else {
- index = s->ar_index & 0x1f;
- switch(index) {
- case 0x00 ... 0x0f:
- s->ar[index] = val & 0x3f;
- break;
- case 0x10:
- s->ar[index] = val & ~0x10;
- break;
- case 0x11:
- s->ar[index] = val;
- break;
- case 0x12:
- s->ar[index] = val & ~0xc0;
- break;
- case 0x13:
- s->ar[index] = val & ~0xf0;
- break;
- case 0x14:
- s->ar[index] = val & ~0xf0;
- break;
- default:
- break;
- }
- }
- s->ar_flip_flop ^= 1;
- break;
- case 0x3c2:
- s->msr = val & ~0x10;
- break;
- case 0x3c4:
- s->sr_index = val & 7;
- break;
- case 0x3c5:
-#ifdef DEBUG_VGA_REG
- printf("vga: write SR%x = 0x%02x\n", s->sr_index, val);
-#endif
- s->sr[s->sr_index] = val & sr_mask[s->sr_index];
- break;
- case 0x3c7:
- s->dac_read_index = val;
- s->dac_sub_index = 0;
- s->dac_state = 3;
- break;
- case 0x3c8:
- s->dac_write_index = val;
- s->dac_sub_index = 0;
- s->dac_state = 0;
- break;
- case 0x3c9:
- s->dac_cache[s->dac_sub_index] = val;
- if (++s->dac_sub_index == 3) {
- memcpy(&s->palette[s->dac_write_index * 3], s->dac_cache, 3);
- s->dac_sub_index = 0;
- s->dac_write_index++;
- }
- break;
- case 0x3ce:
- s->gr_index = val & 0x0f;
- break;
- case 0x3cf:
-#ifdef DEBUG_VGA_REG
- printf("vga: write GR%x = 0x%02x\n", s->gr_index, val);
-#endif
- s->gr[s->gr_index] = val & gr_mask[s->gr_index];
- break;
- case 0x3b4:
- case 0x3d4:
- s->cr_index = val;
- break;
- case 0x3b5:
- case 0x3d5:
-#ifdef DEBUG_VGA_REG
- printf("vga: write CR%x = 0x%02x\n", s->cr_index, val);
-#endif
- /* handle CR0-7 protection */
- if ((s->cr[0x11] & 0x80) && s->cr_index <= 7) {
- /* can always write bit 4 of CR7 */
- if (s->cr_index == 7)
- s->cr[7] = (s->cr[7] & ~0x10) | (val & 0x10);
- return;
- }
- switch(s->cr_index) {
- case 0x01: /* horizontal display end */
- case 0x07:
- case 0x09:
- case 0x0c:
- case 0x0d:
- case 0x12: /* veritcal display end */
- s->cr[s->cr_index] = val;
- break;
-
-#ifdef CONFIG_S3VGA
- /* S3 registers */
- case 0x2d:
- case 0x2e:
- case 0x2f:
- case 0x30:
- /* chip ID, cannot write */
- break;
- case 0x31:
- /* update start address */
- {
- int v;
- s->cr[s->cr_index] = val;
- v = (val >> 4) & 3;
- s->cr[0x69] = (s->cr[69] & ~0x03) | v;
- }
- break;
- case 0x51:
- /* update start address */
- {
- int v;
- s->cr[s->cr_index] = val;
- v = val & 3;
- s->cr[0x69] = (s->cr[69] & ~0x0c) | (v << 2);
- }
- break;
-#endif
- default:
- s->cr[s->cr_index] = val;
- break;
- }
-#ifdef DEBUG_S3
- if (s->cr_index >= 0x20)
- printf("S3: CR write index=0x%x val=0x%x\n",
- s->cr_index, val);
-#endif
- break;
- case 0x3ba:
- case 0x3da:
- s->fcr = val & 0x10;
- break;
- }
-}
-
-#ifdef CONFIG_BOCHS_VBE
-static uint32_t vbe_ioport_read_index(void *opaque, uint32_t addr)
-{
- VGAState *s = opaque;
- uint32_t val;
- val = s->vbe_index;
- return val;
-}
-
-static uint32_t vbe_ioport_read_data(void *opaque, uint32_t addr)
-{
- VGAState *s = opaque;
- uint32_t val;
-
- if (s->vbe_index <= VBE_DISPI_INDEX_NB)
- val = s->vbe_regs[s->vbe_index];
- else
- val = 0;
-#ifdef DEBUG_BOCHS_VBE
- printf("VBE: read index=0x%x val=0x%x\n", s->vbe_index, val);
-#endif
- return val;
-}
-
-static void vbe_ioport_write_index(void *opaque, uint32_t addr, uint32_t val)
-{
- VGAState *s = opaque;
- s->vbe_index = val;
-}
-
-static void vbe_ioport_write_data(void *opaque, uint32_t addr, uint32_t val)
-{
- VGAState *s = opaque;
-
- if (s->vbe_index <= VBE_DISPI_INDEX_NB) {
-#ifdef DEBUG_BOCHS_VBE
- printf("VBE: write index=0x%x val=0x%x\n", s->vbe_index, val);
-#endif
- switch(s->vbe_index) {
- case VBE_DISPI_INDEX_ID:
- if (val == VBE_DISPI_ID0 ||
- val == VBE_DISPI_ID1 ||
- val == VBE_DISPI_ID2) {
- s->vbe_regs[s->vbe_index] = val;
- }
- break;
- case VBE_DISPI_INDEX_XRES:
- if ((val <= VBE_DISPI_MAX_XRES) && ((val & 7) == 0)) {
- s->vbe_regs[s->vbe_index] = val;
- }
- break;
- case VBE_DISPI_INDEX_YRES:
- if (val <= VBE_DISPI_MAX_YRES) {
- s->vbe_regs[s->vbe_index] = val;
- }
- break;
- case VBE_DISPI_INDEX_BPP:
- if (val == 0)
- val = 8;
- if (val == 4 || val == 8 || val == 15 ||
- val == 16 || val == 24 || val == 32) {
- s->vbe_regs[s->vbe_index] = val;
- }
- break;
- case VBE_DISPI_INDEX_BANK:
- val &= s->vbe_bank_mask;
- s->vbe_regs[s->vbe_index] = val;
- s->bank_offset = (val << 16);
- break;
- case VBE_DISPI_INDEX_ENABLE:
- if (val & VBE_DISPI_ENABLED) {
- int h, shift_control;
-
- s->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] =
- s->vbe_regs[VBE_DISPI_INDEX_XRES];
- s->vbe_regs[VBE_DISPI_INDEX_VIRT_HEIGHT] =
- s->vbe_regs[VBE_DISPI_INDEX_YRES];
- s->vbe_regs[VBE_DISPI_INDEX_X_OFFSET] = 0;
- s->vbe_regs[VBE_DISPI_INDEX_Y_OFFSET] = 0;
-
- if (s->vbe_regs[VBE_DISPI_INDEX_BPP] == 4)
- s->vbe_line_offset = s->vbe_regs[VBE_DISPI_INDEX_XRES] >> 1;
- else
- s->vbe_line_offset = s->vbe_regs[VBE_DISPI_INDEX_XRES] *
- ((s->vbe_regs[VBE_DISPI_INDEX_BPP] + 7) >> 3);
- s->vbe_start_addr = 0;
-
- /* clear the screen (should be done in BIOS) */
- if (!(val & VBE_DISPI_NOCLEARMEM)) {
- memset(s->vram_ptr, 0,
- s->vbe_regs[VBE_DISPI_INDEX_YRES] * s->vbe_line_offset);
- }
-
- /* we initialize the VGA graphic mode (should be done
- in BIOS) */
- s->gr[0x06] = (s->gr[0x06] & ~0x0c) | 0x05; /* graphic mode + memory map 1 */
- s->cr[0x17] |= 3; /* no CGA modes */
- s->cr[0x13] = s->vbe_line_offset >> 3;
- /* width */
- s->cr[0x01] = (s->vbe_regs[VBE_DISPI_INDEX_XRES] >> 3) - 1;
- /* height */
- h = s->vbe_regs[VBE_DISPI_INDEX_YRES] - 1;
- s->cr[0x12] = h;
- s->cr[0x07] = (s->cr[0x07] & ~0x42) |
- ((h >> 7) & 0x02) | ((h >> 3) & 0x40);
- /* line compare to 1023 */
- s->cr[0x18] = 0xff;
- s->cr[0x07] |= 0x10;
- s->cr[0x09] |= 0x40;
-
- if (s->vbe_regs[VBE_DISPI_INDEX_BPP] == 4) {
- shift_control = 0;
- s->sr[0x01] &= ~8; /* no double line */
- } else {
- shift_control = 2;
- s->sr[4] |= 0x08; /* set chain 4 mode */
- s->sr[2] |= 0x0f; /* activate all planes */
- }
- s->gr[0x05] = (s->gr[0x05] & ~0x60) | (shift_control << 5);
- s->cr[0x09] &= ~0x9f; /* no double scan */
- } else {
- /* XXX: the bios should do that */
- s->bank_offset = 0;
- }
- s->vbe_regs[s->vbe_index] = val;
- break;
- case VBE_DISPI_INDEX_VIRT_WIDTH:
- {
- int w, h, line_offset;
-
- if (val < s->vbe_regs[VBE_DISPI_INDEX_XRES])
- return;
- w = val;
- if (s->vbe_regs[VBE_DISPI_INDEX_BPP] == 4)
- line_offset = w >> 1;
- else
- line_offset = w * ((s->vbe_regs[VBE_DISPI_INDEX_BPP] + 7) >> 3);
- h = s->vram_size / line_offset;
- /* XXX: support weird bochs semantics ? */
- if (h < s->vbe_regs[VBE_DISPI_INDEX_YRES])
- return;
- s->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] = w;
- s->vbe_regs[VBE_DISPI_INDEX_VIRT_HEIGHT] = h;
- s->vbe_line_offset = line_offset;
- }
- break;
- case VBE_DISPI_INDEX_X_OFFSET:
- case VBE_DISPI_INDEX_Y_OFFSET:
- {
- int x;
- s->vbe_regs[s->vbe_index] = val;
- s->vbe_start_addr = s->vbe_line_offset * s->vbe_regs[VBE_DISPI_INDEX_Y_OFFSET];
- x = s->vbe_regs[VBE_DISPI_INDEX_X_OFFSET];
- if (s->vbe_regs[VBE_DISPI_INDEX_BPP] == 4)
- s->vbe_start_addr += x >> 1;
- else
- s->vbe_start_addr += x * ((s->vbe_regs[VBE_DISPI_INDEX_BPP] + 7) >> 3);
- s->vbe_start_addr >>= 2;
- }
- break;
- default:
- break;
- }
- }
-}
-#endif
-
-extern FILE *logfile;
-/* called for accesses between 0xa0000 and 0xc0000 */
-uint32_t vga_mem_readb(void *opaque, target_phys_addr_t addr)
-{
- VGAState *s = opaque;
- int memory_map_mode, plane;
- uint32_t ret;
-
- /* convert to VGA memory offset */
- memory_map_mode = (s->gr[6] >> 2) & 3;
- addr &= 0x1ffff;
- switch(memory_map_mode) {
- case 0:
- break;
- case 1:
- if (addr >= 0x10000)
- return 0xff;
- addr += s->bank_offset;
- break;
- case 2:
- addr -= 0x10000;
- if (addr >= 0x8000)
- return 0xff;
- break;
- default:
- case 3:
- addr -= 0x18000;
- if (addr >= 0x8000)
- return 0xff;
- break;
- }
-
- if (s->sr[4] & 0x08) {
- /* chain 4 mode : simplest access */
- ret = s->vram_ptr[addr];
- } else if (s->gr[5] & 0x10) {
- /* odd/even mode (aka text mode mapping) */
- plane = (s->gr[4] & 2) | (addr & 1);
- ret = s->vram_ptr[((addr & ~1) << 1) | plane];
- } else {
- /* standard VGA latched access */
- s->latch = ((uint32_t *)s->vram_ptr)[addr];
-
- if (!(s->gr[5] & 0x08)) {
- /* read mode 0 */
- plane = s->gr[4];
- ret = GET_PLANE(s->latch, plane);
- } else {
- /* read mode 1 */
- ret = (s->latch ^ mask16[s->gr[2]]) & mask16[s->gr[7]];
- ret |= ret >> 16;
- ret |= ret >> 8;
- ret = (~ret) & 0xff;
- }
- }
- return ret;
-}
-
-static uint32_t vga_mem_readw(void *opaque, target_phys_addr_t addr)
-{
- uint32_t v;
-#ifdef TARGET_WORDS_BIGENDIAN
- v = vga_mem_readb(opaque, addr) << 8;
- v |= vga_mem_readb(opaque, addr + 1);
-#else
- v = vga_mem_readb(opaque, addr);
- v |= vga_mem_readb(opaque, addr + 1) << 8;
-#endif
- return v;
-}
-
-static uint32_t vga_mem_readl(void *opaque, target_phys_addr_t addr)
-{
- uint32_t v;
-#ifdef TARGET_WORDS_BIGENDIAN
- v = vga_mem_readb(opaque, addr) << 24;
- v |= vga_mem_readb(opaque, addr + 1) << 16;
- v |= vga_mem_readb(opaque, addr + 2) << 8;
- v |= vga_mem_readb(opaque, addr + 3);
-#else
- v = vga_mem_readb(opaque, addr);
- v |= vga_mem_readb(opaque, addr + 1) << 8;
- v |= vga_mem_readb(opaque, addr + 2) << 16;
- v |= vga_mem_readb(opaque, addr + 3) << 24;
-#endif
- return v;
-}
-
-/* called for accesses between 0xa0000 and 0xc0000 */
-void vga_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
- VGAState *s = opaque;
- int memory_map_mode, plane, write_mode, b, func_select, mask;
- uint32_t write_mask, bit_mask, set_mask;
-
-#ifdef DEBUG_VGA_MEM
- printf("vga: [0x%x] = 0x%02x\n", addr, val);
-#endif
- /* convert to VGA memory offset */
- memory_map_mode = (s->gr[6] >> 2) & 3;
- addr &= 0x1ffff;
- switch(memory_map_mode) {
- case 0:
- break;
- case 1:
- if (addr >= 0x10000)
- return;
- addr += s->bank_offset;
- break;
- case 2:
- addr -= 0x10000;
- if (addr >= 0x8000)
- return;
- break;
- default:
- case 3:
- addr -= 0x18000;
- if (addr >= 0x8000)
- return;
- break;
- }
-
- if (s->sr[4] & 0x08) {
- /* chain 4 mode : simplest access */
- plane = addr & 3;
- mask = (1 << plane);
- if (s->sr[2] & mask) {
- s->vram_ptr[addr] = val;
-#ifdef DEBUG_VGA_MEM
- printf("vga: chain4: [0x%x]\n", addr);
-#endif
- s->plane_updated |= mask; /* only used to detect font change */
- cpu_physical_memory_set_dirty(s->vram_offset + addr);
- }
- } else if (s->gr[5] & 0x10) {
- /* odd/even mode (aka text mode mapping) */
- plane = (s->gr[4] & 2) | (addr & 1);
- mask = (1 << plane);
- if (s->sr[2] & mask) {
- addr = ((addr & ~1) << 1) | plane;
- s->vram_ptr[addr] = val;
-#ifdef DEBUG_VGA_MEM
- printf("vga: odd/even: [0x%x]\n", addr);
-#endif
- s->plane_updated |= mask; /* only used to detect font change */
- cpu_physical_memory_set_dirty(s->vram_offset + addr);
- }
- } else {
- /* standard VGA latched access */
- write_mode = s->gr[5] & 3;
- switch(write_mode) {
- default:
- case 0:
- /* rotate */
- b = s->gr[3] & 7;
- val = ((val >> b) | (val << (8 - b))) & 0xff;
- val |= val << 8;
- val |= val << 16;
-
- /* apply set/reset mask */
- set_mask = mask16[s->gr[1]];
- val = (val & ~set_mask) | (mask16[s->gr[0]] & set_mask);
- bit_mask = s->gr[8];
- break;
- case 1:
- val = s->latch;
- goto do_write;
- case 2:
- val = mask16[val & 0x0f];
- bit_mask = s->gr[8];
- break;
- case 3:
- /* rotate */
- b = s->gr[3] & 7;
- val = (val >> b) | (val << (8 - b));
-
- bit_mask = s->gr[8] & val;
- val = mask16[s->gr[0]];
- break;
- }
-
- /* apply logical operation */
- func_select = s->gr[3] >> 3;
- switch(func_select) {
- case 0:
- default:
- /* nothing to do */
- break;
- case 1:
- /* and */
- val &= s->latch;
- break;
- case 2:
- /* or */
- val |= s->latch;
- break;
- case 3:
- /* xor */
- val ^= s->latch;
- break;
- }
-
- /* apply bit mask */
- bit_mask |= bit_mask << 8;
- bit_mask |= bit_mask << 16;
- val = (val & bit_mask) | (s->latch & ~bit_mask);
-
- do_write:
- /* mask data according to sr[2] */
- mask = s->sr[2];
- s->plane_updated |= mask; /* only used to detect font change */
- write_mask = mask16[mask];
- ((uint32_t *)s->vram_ptr)[addr] =
- (((uint32_t *)s->vram_ptr)[addr] & ~write_mask) |
- (val & write_mask);
-#ifdef DEBUG_VGA_MEM
- printf("vga: latch: [0x%x] mask=0x%08x val=0x%08x\n",
- addr * 4, write_mask, val);
-#endif
- cpu_physical_memory_set_dirty(s->vram_offset + (addr << 2));
- }
-}
-
-static void vga_mem_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
-#ifdef TARGET_WORDS_BIGENDIAN
- vga_mem_writeb(opaque, addr, (val >> 8) & 0xff);
- vga_mem_writeb(opaque, addr + 1, val & 0xff);
-#else
- vga_mem_writeb(opaque, addr, val & 0xff);
- vga_mem_writeb(opaque, addr + 1, (val >> 8) & 0xff);
-#endif
-}
-
-static void vga_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
-#ifdef TARGET_WORDS_BIGENDIAN
- vga_mem_writeb(opaque, addr, (val >> 24) & 0xff);
- vga_mem_writeb(opaque, addr + 1, (val >> 16) & 0xff);
- vga_mem_writeb(opaque, addr + 2, (val >> 8) & 0xff);
- vga_mem_writeb(opaque, addr + 3, val & 0xff);
-#else
- vga_mem_writeb(opaque, addr, val & 0xff);
- vga_mem_writeb(opaque, addr + 1, (val >> 8) & 0xff);
- vga_mem_writeb(opaque, addr + 2, (val >> 16) & 0xff);
- vga_mem_writeb(opaque, addr + 3, (val >> 24) & 0xff);
-#endif
-}
-
-typedef void vga_draw_glyph8_func(uint8_t *d, int linesize,
- const uint8_t *font_ptr, int h,
- uint32_t fgcol, uint32_t bgcol);
-typedef void vga_draw_glyph9_func(uint8_t *d, int linesize,
- const uint8_t *font_ptr, int h,
- uint32_t fgcol, uint32_t bgcol, int dup9);
-typedef void vga_draw_line_func(VGAState *s1, uint8_t *d,
- const uint8_t *s, int width);
-
-static inline unsigned int rgb_to_pixel8(unsigned int r, unsigned int g, unsigned b)
-{
- return ((r >> 5) << 5) | ((g >> 5) << 2) | (b >> 6);
-}
-
-static inline unsigned int rgb_to_pixel15(unsigned int r, unsigned int g, unsigned b)
-{
- return ((r >> 3) << 10) | ((g >> 3) << 5) | (b >> 3);
-}
-
-static inline unsigned int rgb_to_pixel16(unsigned int r, unsigned int g, unsigned b)
-{
- return ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3);
-}
-
-static inline unsigned int rgb_to_pixel32(unsigned int r, unsigned int g, unsigned b)
-{
- return (r << 16) | (g << 8) | b;
-}
-
-#define DEPTH 8
-#include "vga_template.h"
-
-#define DEPTH 15
-#include "vga_template.h"
-
-#define DEPTH 16
-#include "vga_template.h"
-
-#define DEPTH 32
-#include "vga_template.h"
-
-static unsigned int rgb_to_pixel8_dup(unsigned int r, unsigned int g, unsigned b)
-{
- unsigned int col;
- col = rgb_to_pixel8(r, g, b);
- col |= col << 8;
- col |= col << 16;
- return col;
-}
-
-static unsigned int rgb_to_pixel15_dup(unsigned int r, unsigned int g, unsigned b)
-{
- unsigned int col;
- col = rgb_to_pixel15(r, g, b);
- col |= col << 16;
- return col;
-}
-
-static unsigned int rgb_to_pixel16_dup(unsigned int r, unsigned int g, unsigned b)
-{
- unsigned int col;
- col = rgb_to_pixel16(r, g, b);
- col |= col << 16;
- return col;
-}
-
-static unsigned int rgb_to_pixel32_dup(unsigned int r, unsigned int g, unsigned b)
-{
- unsigned int col;
- col = rgb_to_pixel32(r, g, b);
- return col;
-}
-
-/* return true if the palette was modified */
-static int update_palette16(VGAState *s)
-{
- int full_update, i;
- uint32_t v, col, *palette;
-
- full_update = 0;
- palette = s->last_palette;
- for(i = 0; i < 16; i++) {
- v = s->ar[i];
- if (s->ar[0x10] & 0x80)
- v = ((s->ar[0x14] & 0xf) << 4) | (v & 0xf);
- else
- v = ((s->ar[0x14] & 0xc) << 4) | (v & 0x3f);
- v = v * 3;
- col = s->rgb_to_pixel(c6_to_8(s->palette[v]),
- c6_to_8(s->palette[v + 1]),
- c6_to_8(s->palette[v + 2]));
- if (col != palette[i]) {
- full_update = 1;
- palette[i] = col;
- }
- }
- return full_update;
-}
-
-/* return true if the palette was modified */
-static int update_palette256(VGAState *s)
-{
- int full_update, i;
- uint32_t v, col, *palette;
-
- full_update = 0;
- palette = s->last_palette;
- v = 0;
- for(i = 0; i < 256; i++) {
- col = s->rgb_to_pixel(c6_to_8(s->palette[v]),
- c6_to_8(s->palette[v + 1]),
- c6_to_8(s->palette[v + 2]));
- if (col != palette[i]) {
- full_update = 1;
- palette[i] = col;
- }
- v += 3;
- }
- return full_update;
-}
-
-static void vga_get_offsets(VGAState *s,
- uint32_t *pline_offset,
- uint32_t *pstart_addr)
-{
- uint32_t start_addr, line_offset;
-#ifdef CONFIG_BOCHS_VBE
- if (s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED) {
- line_offset = s->vbe_line_offset;
- start_addr = s->vbe_start_addr;
- } else
-#endif
- {
- /* compute line_offset in bytes */
- line_offset = s->cr[0x13];
-#ifdef CONFIG_S3VGA
- {
- uinr32_t v;
- v = (s->cr[0x51] >> 4) & 3; /* S3 extension */
- if (v == 0)
- v = (s->cr[0x43] >> 2) & 1; /* S3 extension */
- line_offset |= (v << 8);
- }
-#endif
- line_offset <<= 3;
-
- /* starting address */
- start_addr = s->cr[0x0d] | (s->cr[0x0c] << 8);
-#ifdef CONFIG_S3VGA
- start_addr |= (s->cr[0x69] & 0x1f) << 16; /* S3 extension */
-#endif
- }
- *pline_offset = line_offset;
- *pstart_addr = start_addr;
-}
-
-/* update start_addr and line_offset. Return TRUE if modified */
-static int update_basic_params(VGAState *s)
-{
- int full_update;
- uint32_t start_addr, line_offset, line_compare;
-
- full_update = 0;
-
- s->get_offsets(s, &line_offset, &start_addr);
- /* line compare */
- line_compare = s->cr[0x18] |
- ((s->cr[0x07] & 0x10) << 4) |
- ((s->cr[0x09] & 0x40) << 3);
-
- if (line_offset != s->line_offset ||
- start_addr != s->start_addr ||
- line_compare != s->line_compare) {
- s->line_offset = line_offset;
- s->start_addr = start_addr;
- s->line_compare = line_compare;
- full_update = 1;
- }
- return full_update;
-}
-
-static inline int get_depth_index(int depth)
-{
- switch(depth) {
- default:
- case 8:
- return 0;
- case 15:
- return 1;
- case 16:
- return 2;
- case 32:
- return 3;
- }
-}
-
-static vga_draw_glyph8_func *vga_draw_glyph8_table[4] = {
- vga_draw_glyph8_8,
- vga_draw_glyph8_16,
- vga_draw_glyph8_16,
- vga_draw_glyph8_32,
-};
-
-static vga_draw_glyph8_func *vga_draw_glyph16_table[4] = {
- vga_draw_glyph16_8,
- vga_draw_glyph16_16,
- vga_draw_glyph16_16,
- vga_draw_glyph16_32,
-};
-
-static vga_draw_glyph9_func *vga_draw_glyph9_table[4] = {
- vga_draw_glyph9_8,
- vga_draw_glyph9_16,
- vga_draw_glyph9_16,
- vga_draw_glyph9_32,
-};
-
-static const uint8_t cursor_glyph[32 * 4] = {
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-};
-
-/*
- * Text mode update
- * Missing:
- * - double scan
- * - double width
- * - underline
- * - flashing
- */
-static void vga_draw_text(VGAState *s, int full_update)
-{
- int cx, cy, cheight, cw, ch, cattr, height, width, ch_attr;
- int cx_min, cx_max, linesize, x_incr;
- uint32_t offset, fgcol, bgcol, v, cursor_offset;
- uint8_t *d1, *d, *src, *s1, *dest, *cursor_ptr;
- const uint8_t *font_ptr, *font_base[2];
- int dup9, line_offset, depth_index;
- uint32_t *palette;
- uint32_t *ch_attr_ptr;
- vga_draw_glyph8_func *vga_draw_glyph8;
- vga_draw_glyph9_func *vga_draw_glyph9;
-
- full_update |= update_palette16(s);
- palette = s->last_palette;
-
- /* compute font data address (in plane 2) */
- v = s->sr[3];
- offset = (((v >> 4) & 1) | ((v << 1) & 6)) * 8192 * 4 + 2;
- if (offset != s->font_offsets[0]) {
- s->font_offsets[0] = offset;
- full_update = 1;
- }
- font_base[0] = s->vram_ptr + offset;
-
- offset = (((v >> 5) & 1) | ((v >> 1) & 6)) * 8192 * 4 + 2;
- font_base[1] = s->vram_ptr + offset;
- if (offset != s->font_offsets[1]) {
- s->font_offsets[1] = offset;
- full_update = 1;
- }
- if (s->plane_updated & (1 << 2)) {
- /* if the plane 2 was modified since the last display, it
- indicates the font may have been modified */
- s->plane_updated = 0;
- full_update = 1;
- }
- full_update |= update_basic_params(s);
-
- line_offset = s->line_offset;
- s1 = s->vram_ptr + (s->start_addr * 4);
-
- /* total width & height */
- cheight = (s->cr[9] & 0x1f) + 1;
- cw = 8;
- if (!(s->sr[1] & 0x01))
- cw = 9;
- if (s->sr[1] & 0x08)
- cw = 16; /* NOTE: no 18 pixel wide */
- x_incr = cw * ((s->ds->depth + 7) >> 3);
- width = (s->cr[0x01] + 1);
- if (s->cr[0x06] == 100) {
- /* ugly hack for CGA 160x100x16 - explain me the logic */
- height = 100;
- } else {
- height = s->cr[0x12] |
- ((s->cr[0x07] & 0x02) << 7) |
- ((s->cr[0x07] & 0x40) << 3);
- height = (height + 1) / cheight;
- }
- if ((height * width) > CH_ATTR_SIZE) {
- /* better than nothing: exit if transient size is too big */
- return;
- }
-
- if (width != s->last_width || height != s->last_height ||
- cw != s->last_cw || cheight != s->last_ch) {
- s->last_scr_width = width * cw;
- s->last_scr_height = height * cheight;
- dpy_resize(s->ds, s->last_scr_width, s->last_scr_height);
- s->last_width = width;
- s->last_height = height;
- s->last_ch = cheight;
- s->last_cw = cw;
- full_update = 1;
- }
- cursor_offset = ((s->cr[0x0e] << 8) | s->cr[0x0f]) - s->start_addr;
- if (cursor_offset != s->cursor_offset ||
- s->cr[0xa] != s->cursor_start ||
- s->cr[0xb] != s->cursor_end) {
- /* if the cursor position changed, we update the old and new
- chars */
- if (s->cursor_offset < CH_ATTR_SIZE)
- s->last_ch_attr[s->cursor_offset] = -1;
- if (cursor_offset < CH_ATTR_SIZE)
- s->last_ch_attr[cursor_offset] = -1;
- s->cursor_offset = cursor_offset;
- s->cursor_start = s->cr[0xa];
- s->cursor_end = s->cr[0xb];
- }
- cursor_ptr = s->vram_ptr + (s->start_addr + cursor_offset) * 4;
-
- depth_index = get_depth_index(s->ds->depth);
- if (cw == 16)
- vga_draw_glyph8 = vga_draw_glyph16_table[depth_index];
- else
- vga_draw_glyph8 = vga_draw_glyph8_table[depth_index];
- vga_draw_glyph9 = vga_draw_glyph9_table[depth_index];
-
- dest = s->ds->data;
- linesize = s->ds->linesize;
- ch_attr_ptr = s->last_ch_attr;
- for(cy = 0; cy < height; cy++) {
- d1 = dest;
- src = s1;
- cx_min = width;
- cx_max = -1;
- for(cx = 0; cx < width; cx++) {
- ch_attr = *(uint16_t *)src;
- if (full_update || ch_attr != *ch_attr_ptr) {
- if (cx < cx_min)
- cx_min = cx;
- if (cx > cx_max)
- cx_max = cx;
- *ch_attr_ptr = ch_attr;
-#ifdef WORDS_BIGENDIAN
- ch = ch_attr >> 8;
- cattr = ch_attr & 0xff;
-#else
- ch = ch_attr & 0xff;
- cattr = ch_attr >> 8;
-#endif
- font_ptr = font_base[(cattr >> 3) & 1];
- font_ptr += 32 * 4 * ch;
- bgcol = palette[cattr >> 4];
- fgcol = palette[cattr & 0x0f];
- if (cw != 9) {
- vga_draw_glyph8(d1, linesize,
- font_ptr, cheight, fgcol, bgcol);
- } else {
- dup9 = 0;
- if (ch >= 0xb0 && ch <= 0xdf && (s->ar[0x10] & 0x04))
- dup9 = 1;
- vga_draw_glyph9(d1, linesize,
- font_ptr, cheight, fgcol, bgcol, dup9);
- }
- if (src == cursor_ptr &&
- !(s->cr[0x0a] & 0x20)) {
- int line_start, line_last, h;
- /* draw the cursor */
- line_start = s->cr[0x0a] & 0x1f;
- line_last = s->cr[0x0b] & 0x1f;
- /* XXX: check that */
- if (line_last > cheight - 1)
- line_last = cheight - 1;
- if (line_last >= line_start && line_start < cheight) {
- h = line_last - line_start + 1;
- d = d1 + linesize * line_start;
- if (cw != 9) {
- vga_draw_glyph8(d, linesize,
- cursor_glyph, h, fgcol, bgcol);
- } else {
- vga_draw_glyph9(d, linesize,
- cursor_glyph, h, fgcol, bgcol, 1);
- }
- }
- }
- }
- d1 += x_incr;
- src += 4;
- ch_attr_ptr++;
- }
- if (cx_max != -1) {
- dpy_update(s->ds, cx_min * cw, cy * cheight,
- (cx_max - cx_min + 1) * cw, cheight);
- }
- dest += linesize * cheight;
- s1 += line_offset;
- }
-}
-
-enum {
- VGA_DRAW_LINE2,
- VGA_DRAW_LINE2D2,
- VGA_DRAW_LINE4,
- VGA_DRAW_LINE4D2,
- VGA_DRAW_LINE8D2,
- VGA_DRAW_LINE8,
- VGA_DRAW_LINE15,
- VGA_DRAW_LINE16,
- VGA_DRAW_LINE24,
- VGA_DRAW_LINE32,
- VGA_DRAW_LINE_NB,
-};
-
-static vga_draw_line_func *vga_draw_line_table[4 * VGA_DRAW_LINE_NB] = {
- vga_draw_line2_8,
- vga_draw_line2_16,
- vga_draw_line2_16,
- vga_draw_line2_32,
-
- vga_draw_line2d2_8,
- vga_draw_line2d2_16,
- vga_draw_line2d2_16,
- vga_draw_line2d2_32,
-
- vga_draw_line4_8,
- vga_draw_line4_16,
- vga_draw_line4_16,
- vga_draw_line4_32,
-
- vga_draw_line4d2_8,
- vga_draw_line4d2_16,
- vga_draw_line4d2_16,
- vga_draw_line4d2_32,
-
- vga_draw_line8d2_8,
- vga_draw_line8d2_16,
- vga_draw_line8d2_16,
- vga_draw_line8d2_32,
-
- vga_draw_line8_8,
- vga_draw_line8_16,
- vga_draw_line8_16,
- vga_draw_line8_32,
-
- vga_draw_line15_8,
- vga_draw_line15_15,
- vga_draw_line15_16,
- vga_draw_line15_32,
-
- vga_draw_line16_8,
- vga_draw_line16_15,
- vga_draw_line16_16,
- vga_draw_line16_32,
-
- vga_draw_line24_8,
- vga_draw_line24_15,
- vga_draw_line24_16,
- vga_draw_line24_32,
-
- vga_draw_line32_8,
- vga_draw_line32_15,
- vga_draw_line32_16,
- vga_draw_line32_32,
-};
-
-static int vga_get_bpp(VGAState *s)
-{
- int ret;
-#ifdef CONFIG_BOCHS_VBE
- if (s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED) {
- ret = s->vbe_regs[VBE_DISPI_INDEX_BPP];
- } else
-#endif
- {
- ret = 0;
- }
- return ret;
-}
-
-static void vga_get_resolution(VGAState *s, int *pwidth, int *pheight)
-{
- int width, height;
-
- width = (s->cr[0x01] + 1) * 8;
- height = s->cr[0x12] |
- ((s->cr[0x07] & 0x02) << 7) |
- ((s->cr[0x07] & 0x40) << 3);
- height = (height + 1);
- *pwidth = width;
- *pheight = height;
-}
-
-void vga_invalidate_scanlines(VGAState *s, int y1, int y2)
-{
- int y;
- if (y1 >= VGA_MAX_HEIGHT)
- return;
- if (y2 >= VGA_MAX_HEIGHT)
- y2 = VGA_MAX_HEIGHT;
- for(y = y1; y < y2; y++) {
- s->invalidated_y_table[y >> 5] |= 1 << (y & 0x1f);
- }
-}
-
-static inline int cmp_vram(VGAState *s, int offset, int n)
-{
- long *vp, *sp;
-
- if (s->vram_shadow == NULL)
- return 1;
- vp = (long *)(s->vram_ptr + offset);
- sp = (long *)(s->vram_shadow + offset);
- while ((n -= sizeof(*vp)) >= 0) {
- if (*vp++ != *sp++) {
- memcpy(sp - 1, vp - 1, n + sizeof(*vp));
- return 1;
- }
- }
- return 0;
-}
-
-#ifdef USE_SSE2
-
-#include <signal.h>
-#include <setjmp.h>
-#include <emmintrin.h>
-
-int sse2_ok = 1;
-
-static inline unsigned int cpuid_edx(unsigned int op)
-{
- unsigned int eax, edx;
-
-#ifdef __x86_64__
-#define __bx "rbx"
-#else
-#define __bx "ebx"
-#endif
- __asm__("push %%"__bx"; cpuid; pop %%"__bx
- : "=a" (eax), "=d" (edx)
- : "0" (op)
- : "cx");
-#undef __bx
-
- return edx;
-}
-
-jmp_buf sse_jbuf;
-
-void intr(int sig)
-{
- sse2_ok = 0;
- longjmp(sse_jbuf, 1);
-}
-
-void check_sse2(void)
-{
- /* Check 1: What does CPUID say? */
- if ((cpuid_edx(1) & 0x4000000) == 0) {
- sse2_ok = 0;
- return;
- }
-
- /* Check 2: Can we use SSE2 in anger? */
- signal(SIGILL, intr);
- if (setjmp(sse_jbuf) == 0)
- __asm__("xorps %xmm0,%xmm0\n");
-}
-
-int vram_dirty(VGAState *s, int offset, int n)
-{
- __m128i *sp, *vp;
-
- if (s->vram_shadow == NULL)
- return 1;
- if (sse2_ok == 0)
- return cmp_vram(s, offset, n);
- vp = (__m128i *)(s->vram_ptr + offset);
- sp = (__m128i *)(s->vram_shadow + offset);
- while ((n -= sizeof(*vp)) >= 0) {
- if (_mm_movemask_epi8(_mm_cmpeq_epi8(*sp, *vp)) != 0xffff) {
- while (n >= 0) {
- _mm_store_si128(sp++, _mm_load_si128(vp++));
- n -= sizeof(*vp);
- }
- return 1;
- }
- sp++;
- vp++;
- }
- return 0;
-}
-#else /* !USE_SSE2 */
-int vram_dirty(VGAState *s, int offset, int n)
-{
- return cmp_vram(s, offset, n);
-}
-
-void check_sse2(void)
-{
-}
-#endif /* !USE_SSE2 */
-
-/*
- * graphic modes
- */
-static void vga_draw_graphic(VGAState *s, int full_update)
-{
- int y1, y, update, page_min, page_max, linesize, y_start, double_scan, mask;
- int width, height, shift_control, line_offset, page0, page1, bwidth;
- int disp_width, multi_scan, multi_run;
- uint8_t *d;
- uint32_t v, addr1, addr;
- vga_draw_line_func *vga_draw_line;
-
- full_update |= update_basic_params(s);
-
- s->get_resolution(s, &width, &height);
- disp_width = width;
-
- shift_control = (s->gr[0x05] >> 5) & 3;
- double_scan = (s->cr[0x09] >> 7);
- if (shift_control != 1) {
- multi_scan = (((s->cr[0x09] & 0x1f) + 1) << double_scan) - 1;
- } else {
- /* in CGA modes, multi_scan is ignored */
- /* XXX: is it correct ? */
- multi_scan = double_scan;
- }
- multi_run = multi_scan;
- if (shift_control != s->shift_control ||
- double_scan != s->double_scan) {
- full_update = 1;
- s->shift_control = shift_control;
- s->double_scan = double_scan;
- }
-
- if (shift_control == 0) {
- full_update |= update_palette16(s);
- if (s->sr[0x01] & 8) {
- v = VGA_DRAW_LINE4D2;
- disp_width <<= 1;
- } else {
- v = VGA_DRAW_LINE4;
- }
- } else if (shift_control == 1) {
- full_update |= update_palette16(s);
- if (s->sr[0x01] & 8) {
- v = VGA_DRAW_LINE2D2;
- disp_width <<= 1;
- } else {
- v = VGA_DRAW_LINE2;
- }
- } else {
- switch(s->get_bpp(s)) {
- default:
- case 0:
- full_update |= update_palette256(s);
- v = VGA_DRAW_LINE8D2;
- break;
- case 8:
- full_update |= update_palette256(s);
- v = VGA_DRAW_LINE8;
- break;
- case 15:
- v = VGA_DRAW_LINE15;
- break;
- case 16:
- v = VGA_DRAW_LINE16;
- break;
- case 24:
- v = VGA_DRAW_LINE24;
- break;
- case 32:
- v = VGA_DRAW_LINE32;
- break;
- }
- }
- vga_draw_line = vga_draw_line_table[v * 4 + get_depth_index(s->ds->depth)];
-
- if (disp_width != s->last_width ||
- height != s->last_height) {
- dpy_resize(s->ds, disp_width, height);
- s->last_scr_width = disp_width;
- s->last_scr_height = height;
- s->last_width = disp_width;
- s->last_height = height;
- full_update = 1;
- }
- if (s->cursor_invalidate)
- s->cursor_invalidate(s);
-
- line_offset = s->line_offset;
-#if 0
- printf("w=%d h=%d v=%d line_offset=%d cr[0x09]=0x%02x cr[0x17]=0x%02x linecmp=%d sr[0x01]=0x%02x\n",
- width, height, v, line_offset, s->cr[9], s->cr[0x17], s->line_compare, s->sr[0x01]);
-#endif
- for (y = 0; y < s->vram_size; y += TARGET_PAGE_SIZE)
- if (vram_dirty(s, y, TARGET_PAGE_SIZE))
- cpu_physical_memory_set_dirty(s->vram_offset + y);
- addr1 = (s->start_addr * 4);
- bwidth = width * 4;
- y_start = -1;
- page_min = 0x7fffffff;
- page_max = -1;
- d = s->ds->data;
- linesize = s->ds->linesize;
- y1 = 0;
- for(y = 0; y < height; y++) {
- addr = addr1;
- if (!(s->cr[0x17] & 1)) {
- int shift;
- /* CGA compatibility handling */
- shift = 14 + ((s->cr[0x17] >> 6) & 1);
- addr = (addr & ~(1 << shift)) | ((y1 & 1) << shift);
- }
- if (!(s->cr[0x17] & 2)) {
- addr = (addr & ~0x8000) | ((y1 & 2) << 14);
- }
- page0 = s->vram_offset + (addr & TARGET_PAGE_MASK);
- page1 = s->vram_offset + ((addr + bwidth - 1) & TARGET_PAGE_MASK);
- update = full_update | cpu_physical_memory_is_dirty(page0) |
- cpu_physical_memory_is_dirty(page1);
- if ((page1 - page0) > TARGET_PAGE_SIZE) {
- /* if wide line, can use another page */
- update |= cpu_physical_memory_is_dirty(page0 + TARGET_PAGE_SIZE);
- }
- /* explicit invalidation for the hardware cursor */
- update |= (s->invalidated_y_table[y >> 5] >> (y & 0x1f)) & 1;
- if (update) {
- if (y_start < 0)
- y_start = y;
- if (page0 < page_min)
- page_min = page0;
- if (page1 > page_max)
- page_max = page1;
- vga_draw_line(s, d, s->vram_ptr + addr, width);
- if (s->cursor_draw_line)
- s->cursor_draw_line(s, d, y);
- } else {
- if (y_start >= 0) {
- /* flush to display */
- dpy_update(s->ds, 0, y_start,
- disp_width, y - y_start);
- y_start = -1;
- }
- }
- if (!multi_run) {
- mask = (s->cr[0x17] & 3) ^ 3;
- if ((y1 & mask) == mask)
- addr1 += line_offset;
- y1++;
- multi_run = multi_scan;
- } else {
- multi_run--;
- }
- /* line compare acts on the displayed lines */
- if (y == s->line_compare)
- addr1 = 0;
- d += linesize;
- }
- if (y_start >= 0) {
- /* flush to display */
- dpy_update(s->ds, 0, y_start,
- disp_width, y - y_start);
- }
- /* reset modified pages */
- if (page_max != -1) {
- cpu_physical_memory_reset_dirty(page_min, page_max + TARGET_PAGE_SIZE);
- }
- memset(s->invalidated_y_table, 0, ((height + 31) >> 5) * 4);
-}
-
-static void vga_draw_blank(VGAState *s, int full_update)
-{
- int i, w, val;
- uint8_t *d;
-
- if (!full_update)
- return;
- if (s->last_scr_width <= 0 || s->last_scr_height <= 0)
- return;
- if (s->ds->depth == 8)
- val = s->rgb_to_pixel(0, 0, 0);
- else
- val = 0;
- w = s->last_scr_width * ((s->ds->depth + 7) >> 3);
- d = s->ds->data;
- for(i = 0; i < s->last_scr_height; i++) {
- memset(d, val, w);
- d += s->ds->linesize;
- }
- dpy_update(s->ds, 0, 0,
- s->last_scr_width, s->last_scr_height);
-}
-
-#define GMODE_TEXT 0
-#define GMODE_GRAPH 1
-#define GMODE_BLANK 2
-
-void vga_update_display(void)
-{
- static int loop;
- VGAState *s = vga_state;
- int full_update, graphic_mode;
-
- /*
- * Only update the display every other time. The responsiveness is
- * acceptable and it cuts down on the overhead of the VRAM compare
- * in `vram_dirty'.
- */
- if (loop++ & 1)
- return;
-
- if (s->ds->depth == 0) {
- /* nothing to do */
- } else {
- switch(s->ds->depth) {
- case 8:
- s->rgb_to_pixel = rgb_to_pixel8_dup;
- break;
- case 15:
- s->rgb_to_pixel = rgb_to_pixel15_dup;
- break;
- default:
- case 16:
- s->rgb_to_pixel = rgb_to_pixel16_dup;
- break;
- case 32:
- s->rgb_to_pixel = rgb_to_pixel32_dup;
- break;
- }
-
- full_update = 0;
- if (!(s->ar_index & 0x20)) {
- graphic_mode = GMODE_BLANK;
- } else {
- graphic_mode = s->gr[6] & 1;
- }
- if (graphic_mode != s->graphic_mode) {
- s->graphic_mode = graphic_mode;
- full_update = 1;
- }
-
- switch(graphic_mode) {
- case GMODE_TEXT:
- vga_draw_text(s, full_update);
- break;
- case GMODE_GRAPH:
- vga_draw_graphic(s, full_update);
- break;
- case GMODE_BLANK:
- default:
- vga_draw_blank(s, full_update);
- break;
- }
- }
-}
-
-/* force a full display refresh */
-void vga_invalidate_display(void)
-{
- VGAState *s = vga_state;
-
- s->last_width = -1;
- s->last_height = -1;
-}
-
-static void vga_reset(VGAState *s)
-{
- memset(s, 0, sizeof(VGAState));
-#ifdef CONFIG_S3VGA
- /* chip ID for 8c968 */
- s->cr[0x2d] = 0x88;
- s->cr[0x2e] = 0xb0;
- s->cr[0x2f] = 0x01; /* XXX: check revision code */
- s->cr[0x30] = 0xe1;
-#endif
- s->graphic_mode = -1; /* force full update */
-}
-
-static CPUReadMemoryFunc *vga_mem_read[3] = {
- vga_mem_readb,
- vga_mem_readw,
- vga_mem_readl,
-};
-
-static CPUWriteMemoryFunc *vga_mem_write[3] = {
- vga_mem_writeb,
- vga_mem_writew,
- vga_mem_writel,
-};
-
-static void vga_save(QEMUFile *f, void *opaque)
-{
- VGAState *s = opaque;
-
- qemu_put_be32s(f, &s->latch);
- qemu_put_8s(f, &s->sr_index);
- qemu_put_buffer(f, s->sr, 8);
- qemu_put_8s(f, &s->gr_index);
- qemu_put_buffer(f, s->gr, 16);
- qemu_put_8s(f, &s->ar_index);
- qemu_put_buffer(f, s->ar, 21);
- qemu_put_be32s(f, &s->ar_flip_flop);
- qemu_put_8s(f, &s->cr_index);
- qemu_put_buffer(f, s->cr, 256);
- qemu_put_8s(f, &s->msr);
- qemu_put_8s(f, &s->fcr);
- qemu_put_8s(f, &s->st00);
- qemu_put_8s(f, &s->st01);
-
- qemu_put_8s(f, &s->dac_state);
- qemu_put_8s(f, &s->dac_sub_index);
- qemu_put_8s(f, &s->dac_read_index);
- qemu_put_8s(f, &s->dac_write_index);
- qemu_put_buffer(f, s->dac_cache, 3);
- qemu_put_buffer(f, s->palette, 768);
-
- qemu_put_be32s(f, &s->bank_offset);
-#ifdef CONFIG_BOCHS_VBE
- qemu_put_byte(f, 1);
- qemu_put_be16s(f, &s->vbe_index);
- for(i = 0; i < VBE_DISPI_INDEX_NB; i++)
- qemu_put_be16s(f, &s->vbe_regs[i]);
- qemu_put_be32s(f, &s->vbe_start_addr);
- qemu_put_be32s(f, &s->vbe_line_offset);
- qemu_put_be32s(f, &s->vbe_bank_mask);
-#else
- qemu_put_byte(f, 0);
-#endif
-}
-
-static int vga_load(QEMUFile *f, void *opaque, int version_id)
-{
- VGAState *s = opaque;
- int is_vbe;
-
- if (version_id != 1)
- return -EINVAL;
-
- qemu_get_be32s(f, &s->latch);
- qemu_get_8s(f, &s->sr_index);
- qemu_get_buffer(f, s->sr, 8);
- qemu_get_8s(f, &s->gr_index);
- qemu_get_buffer(f, s->gr, 16);
- qemu_get_8s(f, &s->ar_index);
- qemu_get_buffer(f, s->ar, 21);
- qemu_get_be32s(f, &s->ar_flip_flop);
- qemu_get_8s(f, &s->cr_index);
- qemu_get_buffer(f, s->cr, 256);
- qemu_get_8s(f, &s->msr);
- qemu_get_8s(f, &s->fcr);
- qemu_get_8s(f, &s->st00);
- qemu_get_8s(f, &s->st01);
-
- qemu_get_8s(f, &s->dac_state);
- qemu_get_8s(f, &s->dac_sub_index);
- qemu_get_8s(f, &s->dac_read_index);
- qemu_get_8s(f, &s->dac_write_index);
- qemu_get_buffer(f, s->dac_cache, 3);
- qemu_get_buffer(f, s->palette, 768);
-
- qemu_get_be32s(f, &s->bank_offset);
- is_vbe = qemu_get_byte(f);
-#ifdef CONFIG_BOCHS_VBE
- if (!is_vbe)
- return -EINVAL;
- qemu_get_be16s(f, &s->vbe_index);
- for(i = 0; i < VBE_DISPI_INDEX_NB; i++)
- qemu_get_be16s(f, &s->vbe_regs[i]);
- qemu_get_be32s(f, &s->vbe_start_addr);
- qemu_get_be32s(f, &s->vbe_line_offset);
- qemu_get_be32s(f, &s->vbe_bank_mask);
-#else
- if (is_vbe)
- return -EINVAL;
-#endif
-
- /* force refresh */
- s->graphic_mode = -1;
- return 0;
-}
-
-static void vga_map(PCIDevice *pci_dev, int region_num,
- uint32_t addr, uint32_t size, int type)
-{
- VGAState *s = vga_state;
-
- cpu_register_physical_memory(addr, s->vram_size, s->vram_offset);
-}
-
-/* do the same job as vgabios before vgabios get ready */
-void vga_bios_init(VGAState *s)
-{
- uint8_t palette_model[192] = {
- 0, 0, 0, 0, 0, 170, 0, 170, 0, 0, 170, 170, 170, 0, 0, 170,
- 0, 170, 170, 85, 0, 170, 170, 170, 85, 85, 85, 85, 85, 255, 85, 255,
- 85, 85, 255, 255, 255, 85, 85, 255, 85, 255, 255, 255, 85, 255, 255, 255,
- 0, 21, 0, 0, 21, 42, 0, 63, 0, 0, 63, 42, 42, 21, 0, 42,
- 21, 42, 42, 63, 0, 42, 63, 42, 0, 21, 21, 0, 21, 63, 0, 63,
- 21, 0, 63, 63, 42, 21, 21, 42, 21, 63, 42, 63, 21, 42, 63, 63,
- 21, 0, 0, 21, 0, 42, 21, 42, 0, 21, 42, 42, 63, 0, 0, 63,
- 0, 42, 63, 42, 0, 63, 42, 42, 21, 0, 21, 21, 0, 63, 21, 42,
- 21, 21, 42, 63, 63, 0, 21, 63, 0, 63, 63, 42, 21, 63, 42, 63,
- 21, 21, 0, 21, 21, 42, 21, 63, 0, 21, 63, 42, 63, 21, 0, 63,
- 21, 42, 63, 63, 0, 63, 63, 42, 21, 21, 21, 21, 21, 63, 21, 63,
- 21, 21, 63, 63, 63, 21, 21, 63, 21, 63, 63, 63, 21, 63, 63, 63
- };
-
- s->latch = 0;
-
- s->sr_index = 3;
- s->sr[0] = 3;
- s->sr[1] = 0;
- s->sr[2] = 3;
- s->sr[3] = 0;
- s->sr[4] = 2;
- s->sr[5] = 0;
- s->sr[6] = 0;
- s->sr[7] = 0;
-
- s->gr_index = 5;
- s->gr[0] = 0;
- s->gr[1] = 0;
- s->gr[2] = 0;
- s->gr[3] = 0;
- s->gr[4] = 0;
- s->gr[5] = 16;
- s->gr[6] = 14;
- s->gr[7] = 15;
- s->gr[8] = 255;
-
- /*changed by out 0x03c0*/
- s->ar_index = 32;
- s->ar[0] = 0;
- s->ar[1] = 1;
- s->ar[2] = 2;
- s->ar[3] = 3;
- s->ar[4] = 4;
- s->ar[5] = 5;
- s->ar[6] = 6;
- s->ar[7] = 7;
- s->ar[8] = 8;
- s->ar[9] = 9;
- s->ar[10] = 10;
- s->ar[11] = 11;
- s->ar[12] = 12;
- s->ar[13] = 13;
- s->ar[14] = 14;
- s->ar[15] = 15;
- s->ar[16] = 12;
- s->ar[17] = 0;
- s->ar[18] = 15;
- s->ar[19] = 8;
- s->ar[20] = 0;
-
- s->ar_flip_flop = 1;
-
- s->cr_index = 15;
- s->cr[0] = 95;
- s->cr[1] = 79;
- s->cr[2] = 80;
- s->cr[3] = 130;
- s->cr[4] = 85;
- s->cr[5] = 129;
- s->cr[6] = 191;
- s->cr[7] = 31;
- s->cr[8] = 0;
- s->cr[9] = 79;
- s->cr[10] = 14;
- s->cr[11] = 15;
- s->cr[12] = 0;
- s->cr[13] = 0;
- s->cr[14] = 5;
- s->cr[15] = 160;
- s->cr[16] = 156;
- s->cr[17] = 142;
- s->cr[18] = 143;
- s->cr[19] = 40;
- s->cr[20] = 31;
- s->cr[21] = 150;
- s->cr[22] = 185;
- s->cr[23] = 163;
- s->cr[24] = 255;
-
- s->msr = 103;
- s->fcr = 0;
- s->st00 = 0;
- s->st01 = 0;
-
- /*dac_* & platte will be initialized by os through out 0x03c8 & out 0c03c9(1:3) */
- s->dac_state = 0;
- s->dac_sub_index = 0;
- s->dac_read_index = 0;
- s->dac_write_index = 16;
- s->dac_cache[0] = 255;
- s->dac_cache[1] = 255;
- s->dac_cache[2] = 255;
-
- /*platte*/
- memcpy(s->palette, palette_model, 192);
-
- s->bank_offset= 0;
- s->graphic_mode = -1;
-
- /* TODO:add vbe support if enable it */
-
-}
-
-/* when used on xen environment, the vga_ram_base is not used */
-void vga_common_init(VGAState *s, DisplayState *ds, uint8_t *vga_ram_base,
- unsigned long vga_ram_offset, int vga_ram_size)
-{
- int i, j, v, b;
-
- for(i = 0;i < 256; i++) {
- v = 0;
- for(j = 0; j < 8; j++) {
- v |= ((i >> j) & 1) << (j * 4);
- }
- expand4[i] = v;
-
- v = 0;
- for(j = 0; j < 4; j++) {
- v |= ((i >> (2 * j)) & 3) << (j * 4);
- }
- expand2[i] = v;
- }
- for(i = 0; i < 16; i++) {
- v = 0;
- for(j = 0; j < 4; j++) {
- b = ((i >> j) & 1);
- v |= b << (2 * j);
- v |= b << (2 * j + 1);
- }
- expand4to8[i] = v;
- }
-
- vga_reset(s);
-
- /* qemu's vga mem is not detached from phys_ram_base and can cause DM abort
- * when guest write vga mem, so allocate a new one */
- s->vram_ptr = qemu_malloc(vga_ram_size);
- check_sse2();
- s->vram_shadow = qemu_malloc(vga_ram_size+TARGET_PAGE_SIZE+1);
- if (s->vram_shadow == NULL)
- fprintf(stderr, "Cannot allocate %d bytes for VRAM shadow, "
- "mouse will be slow\n", vga_ram_size);
- s->vram_shadow = (uint8_t *)((long)(s->vram_shadow + TARGET_PAGE_SIZE - 1)
- & ~(TARGET_PAGE_SIZE - 1));
- s->vram_offset = vga_ram_offset;
- s->vram_size = vga_ram_size;
- s->ds = ds;
- s->get_bpp = vga_get_bpp;
- s->get_offsets = vga_get_offsets;
- s->get_resolution = vga_get_resolution;
- /* XXX: currently needed for display */
- vga_state = s;
- vga_bios_init(s);
-}
-
-
-int vga_initialize(PCIBus *bus, DisplayState *ds, uint8_t *vga_ram_base,
- unsigned long vga_ram_offset, int vga_ram_size)
-{
- VGAState *s;
-
- s = qemu_mallocz(sizeof(VGAState));
- if (!s)
- return -1;
-
- vga_common_init(s, ds, vga_ram_base, vga_ram_offset, vga_ram_size);
-
- register_savevm("vga", 0, 1, vga_save, vga_load, s);
-
- register_ioport_write(0x3c0, 16, 1, vga_ioport_write, s);
-
- register_ioport_write(0x3b4, 2, 1, vga_ioport_write, s);
- register_ioport_write(0x3d4, 2, 1, vga_ioport_write, s);
- register_ioport_write(0x3ba, 1, 1, vga_ioport_write, s);
- register_ioport_write(0x3da, 1, 1, vga_ioport_write, s);
-
- register_ioport_read(0x3c0, 16, 1, vga_ioport_read, s);
-
- register_ioport_read(0x3b4, 2, 1, vga_ioport_read, s);
- register_ioport_read(0x3d4, 2, 1, vga_ioport_read, s);
- register_ioport_read(0x3ba, 1, 1, vga_ioport_read, s);
- register_ioport_read(0x3da, 1, 1, vga_ioport_read, s);
- s->bank_offset = 0;
-
-#ifdef CONFIG_BOCHS_VBE
- s->vbe_regs[VBE_DISPI_INDEX_ID] = VBE_DISPI_ID0;
- s->vbe_bank_mask = ((s->vram_size >> 16) - 1);
-#if defined (TARGET_I386)
- register_ioport_read(0x1ce, 1, 2, vbe_ioport_read_index, s);
- register_ioport_read(0x1cf, 1, 2, vbe_ioport_read_data, s);
-
- register_ioport_write(0x1ce, 1, 2, vbe_ioport_write_index, s);
- register_ioport_write(0x1cf, 1, 2, vbe_ioport_write_data, s);
-
- /* old Bochs IO ports */
- register_ioport_read(0xff80, 1, 2, vbe_ioport_read_index, s);
- register_ioport_read(0xff81, 1, 2, vbe_ioport_read_data, s);
-
- register_ioport_write(0xff80, 1, 2, vbe_ioport_write_index, s);
- register_ioport_write(0xff81, 1, 2, vbe_ioport_write_data, s);
-#else
- register_ioport_read(0x1ce, 1, 2, vbe_ioport_read_index, s);
- register_ioport_read(0x1d0, 1, 2, vbe_ioport_read_data, s);
-
- register_ioport_write(0x1ce, 1, 2, vbe_ioport_write_index, s);
- register_ioport_write(0x1d0, 1, 2, vbe_ioport_write_data, s);
-#endif
-#endif /* CONFIG_BOCHS_VBE */
-
- vga_io_memory = cpu_register_io_memory(0, vga_mem_read, vga_mem_write, s);
- cpu_register_physical_memory(isa_mem_base + 0x000a0000, 0x20000,
- vga_io_memory);
-
- if (bus) {
- PCIDevice *d;
- uint8_t *pci_conf;
-
- d = pci_register_device(bus, "VGA",
- sizeof(PCIDevice),
- -1, NULL, NULL);
- pci_conf = d->config;
- pci_conf[0x00] = 0x34; // dummy VGA (same as Bochs ID)
- pci_conf[0x01] = 0x12;
- pci_conf[0x02] = 0x11;
- pci_conf[0x03] = 0x11;
- pci_conf[0x0a] = 0x00; // VGA controller
- pci_conf[0x0b] = 0x03;
- pci_conf[0x0e] = 0x00; // header_type
-
- /* XXX: vga_ram_size must be a power of two */
- pci_register_io_region(d, 0, vga_ram_size,
- PCI_ADDRESS_SPACE_MEM_PREFETCH, vga_map);
- } else {
-#ifdef CONFIG_BOCHS_VBE
- /* XXX: use optimized standard vga accesses */
- cpu_register_physical_memory(VBE_DISPI_LFB_PHYSICAL_ADDRESS,
- vga_ram_size, vga_ram_offset);
-#endif
- }
-
- return 0;
-}
-
-void *vga_update_vram(VGAState *s, void *vga_ram_base, int vga_ram_size)
-{
- uint8_t *old_pointer;
-
- if (s->vram_size != vga_ram_size)
- {
- fprintf(stderr, "No support to change vga_ram_size\n");
- return NULL;
- }
-
- if ( !vga_ram_base )
- {
- vga_ram_base = qemu_malloc(vga_ram_size);
- if (!vga_ram_base)
- {
- fprintf(stderr, "reallocate error\n");
- return NULL;
- }
- }
-
- /* XXX lock needed? */
- memcpy(vga_ram_base, s->vram_ptr, vga_ram_size);
- old_pointer = s->vram_ptr;
- s->vram_ptr = vga_ram_base;
-
- return old_pointer;
-}
-
-/********************************************************/
-/* vga screen dump */
-
-static int vga_save_w, vga_save_h;
-
-static void vga_save_dpy_update(DisplayState *s,
- int x, int y, int w, int h)
-{
-}
-
-static void vga_save_dpy_resize(DisplayState *s, int w, int h)
-{
- s->linesize = w * 4;
- s->data = qemu_malloc(h * s->linesize);
- vga_save_w = w;
- vga_save_h = h;
-}
-
-static void vga_save_dpy_refresh(DisplayState *s)
-{
-}
-
-static int ppm_save(const char *filename, uint8_t *data,
- int w, int h, int linesize)
-{
- FILE *f;
- uint8_t *d, *d1;
- unsigned int v;
- int y, x;
-
- f = fopen(filename, "wb");
- if (!f)
- return -1;
- fprintf(f, "P6\n%d %d\n%d\n",
- w, h, 255);
- d1 = data;
- for(y = 0; y < h; y++) {
- d = d1;
- for(x = 0; x < w; x++) {
- v = *(uint32_t *)d;
- fputc((v >> 16) & 0xff, f);
- fputc((v >> 8) & 0xff, f);
- fputc((v) & 0xff, f);
- d += 4;
- }
- d1 += linesize;
- }
- fclose(f);
- return 0;
-}
-
-/* save the vga display in a PPM image even if no display is
- available */
-void vga_screen_dump(const char *filename)
-{
- VGAState *s = vga_state;
- DisplayState *saved_ds, ds1, *ds = &ds1;
-
- /* XXX: this is a little hackish */
- vga_invalidate_display();
- saved_ds = s->ds;
-
- memset(ds, 0, sizeof(DisplayState));
- ds->dpy_update = vga_save_dpy_update;
- ds->dpy_resize = vga_save_dpy_resize;
- ds->dpy_refresh = vga_save_dpy_refresh;
- ds->depth = 32;
-
- s->ds = ds;
- s->graphic_mode = -1;
- vga_update_display();
-
- if (ds->data) {
- ppm_save(filename, ds->data, vga_save_w, vga_save_h,
- s->ds->linesize);
- qemu_free(ds->data);
- }
- s->ds = saved_ds;
-}
+++ /dev/null
-/*
- * QEMU internal VGA defines.
- *
- * Copyright (c) 2003-2004 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#define MSR_COLOR_EMULATION 0x01
-#define MSR_PAGE_SELECT 0x20
-
-#define ST01_V_RETRACE 0x08
-#define ST01_DISP_ENABLE 0x01
-
-/* bochs VBE support */
-//#define CONFIG_BOCHS_VBE
-
-#define VBE_DISPI_MAX_XRES 1024
-#define VBE_DISPI_MAX_YRES 768
-
-#define VBE_DISPI_INDEX_ID 0x0
-#define VBE_DISPI_INDEX_XRES 0x1
-#define VBE_DISPI_INDEX_YRES 0x2
-#define VBE_DISPI_INDEX_BPP 0x3
-#define VBE_DISPI_INDEX_ENABLE 0x4
-#define VBE_DISPI_INDEX_BANK 0x5
-#define VBE_DISPI_INDEX_VIRT_WIDTH 0x6
-#define VBE_DISPI_INDEX_VIRT_HEIGHT 0x7
-#define VBE_DISPI_INDEX_X_OFFSET 0x8
-#define VBE_DISPI_INDEX_Y_OFFSET 0x9
-#define VBE_DISPI_INDEX_NB 0xa
-
-#define VBE_DISPI_ID0 0xB0C0
-#define VBE_DISPI_ID1 0xB0C1
-#define VBE_DISPI_ID2 0xB0C2
-
-#define VBE_DISPI_DISABLED 0x00
-#define VBE_DISPI_ENABLED 0x01
-#define VBE_DISPI_LFB_ENABLED 0x40
-#define VBE_DISPI_NOCLEARMEM 0x80
-
-#define VBE_DISPI_LFB_PHYSICAL_ADDRESS 0xE0000000
-
-#ifdef CONFIG_BOCHS_VBE
-
-#define VGA_STATE_COMMON_BOCHS_VBE \
- uint16_t vbe_index; \
- uint16_t vbe_regs[VBE_DISPI_INDEX_NB]; \
- uint32_t vbe_start_addr; \
- uint32_t vbe_line_offset; \
- uint32_t vbe_bank_mask;
-
-#else
-
-#define VGA_STATE_COMMON_BOCHS_VBE
-
-#endif /* !CONFIG_BOCHS_VBE */
-
-#define CH_ATTR_SIZE (160 * 100)
-#define VGA_MAX_HEIGHT 1024
-
-#define VGA_STATE_COMMON \
- uint8_t *vram_ptr; \
- uint8_t *vram_shadow; \
- unsigned long vram_offset; \
- unsigned int vram_size; \
- uint32_t latch; \
- uint8_t sr_index; \
- uint8_t sr[256]; \
- uint8_t gr_index; \
- uint8_t gr[256]; \
- uint8_t ar_index; \
- uint8_t ar[21]; \
- int ar_flip_flop; \
- uint8_t cr_index; \
- uint8_t cr[256]; /* CRT registers */ \
- uint8_t msr; /* Misc Output Register */ \
- uint8_t fcr; /* Feature Control Register */ \
- uint8_t st00; /* status 0 */ \
- uint8_t st01; /* status 1 */ \
- uint8_t dac_state; \
- uint8_t dac_sub_index; \
- uint8_t dac_read_index; \
- uint8_t dac_write_index; \
- uint8_t dac_cache[3]; /* used when writing */ \
- uint8_t palette[768]; \
- int32_t bank_offset; \
- int (*get_bpp)(struct VGAState *s); \
- void (*get_offsets)(struct VGAState *s, \
- uint32_t *pline_offset, \
- uint32_t *pstart_addr); \
- void (*get_resolution)(struct VGAState *s, \
- int *pwidth, \
- int *pheight); \
- VGA_STATE_COMMON_BOCHS_VBE \
- /* display refresh support */ \
- DisplayState *ds; \
- uint32_t font_offsets[2]; \
- int graphic_mode; \
- uint8_t shift_control; \
- uint8_t double_scan; \
- uint32_t line_offset; \
- uint32_t line_compare; \
- uint32_t start_addr; \
- uint32_t plane_updated; \
- uint8_t last_cw, last_ch; \
- uint32_t last_width, last_height; /* in chars or pixels */ \
- uint32_t last_scr_width, last_scr_height; /* in pixels */ \
- uint8_t cursor_start, cursor_end; \
- uint32_t cursor_offset; \
- unsigned int (*rgb_to_pixel)(unsigned int r, \
- unsigned int g, unsigned b); \
- /* hardware mouse cursor support */ \
- uint32_t invalidated_y_table[VGA_MAX_HEIGHT / 32]; \
- void (*cursor_invalidate)(struct VGAState *s); \
- void (*cursor_draw_line)(struct VGAState *s, uint8_t *d, int y); \
- /* tell for each page if it has been updated since the last time */ \
- uint32_t last_palette[256]; \
- uint32_t last_ch_attr[CH_ATTR_SIZE]; /* XXX: make it dynamic */
-
-
-typedef struct VGAState {
- VGA_STATE_COMMON
-} VGAState;
-
-static inline int c6_to_8(int v)
-{
- int b;
- v &= 0x3f;
- b = v & 1;
- return (v << 2) | (b << 1) | b;
-}
-
-void vga_common_init(VGAState *s, DisplayState *ds, uint8_t *vga_ram_base,
- unsigned long vga_ram_offset, int vga_ram_size);
-uint32_t vga_mem_readb(void *opaque, target_phys_addr_t addr);
-void vga_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val);
-void vga_invalidate_scanlines(VGAState *s, int y1, int y2);
-
-void vga_draw_cursor_line_8(uint8_t *d1, const uint8_t *src1,
- int poffset, int w,
- unsigned int color0, unsigned int color1,
- unsigned int color_xor);
-void vga_draw_cursor_line_16(uint8_t *d1, const uint8_t *src1,
- int poffset, int w,
- unsigned int color0, unsigned int color1,
- unsigned int color_xor);
-void vga_draw_cursor_line_32(uint8_t *d1, const uint8_t *src1,
- int poffset, int w,
- unsigned int color0, unsigned int color1,
- unsigned int color_xor);
-
-void *vga_update_vram(VGAState *s, void *vga_ram_base, int vga_ram_size);
-extern const uint8_t sr_mask[8];
-extern const uint8_t gr_mask[16];
+++ /dev/null
-/*
- * QEMU VGA Emulator templates
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#if DEPTH == 8
-#define BPP 1
-#define PIXEL_TYPE uint8_t
-#elif DEPTH == 15 || DEPTH == 16
-#define BPP 2
-#define PIXEL_TYPE uint16_t
-#elif DEPTH == 32
-#define BPP 4
-#define PIXEL_TYPE uint32_t
-#else
-#error unsupport depth
-#endif
-
-#if DEPTH != 15
-
-static inline void glue(vga_draw_glyph_line_, DEPTH)(uint8_t *d,
- uint32_t font_data,
- uint32_t xorcol,
- uint32_t bgcol)
-{
-#if BPP == 1
- ((uint32_t *)d)[0] = (dmask16[(font_data >> 4)] & xorcol) ^ bgcol;
- ((uint32_t *)d)[1] = (dmask16[(font_data >> 0) & 0xf] & xorcol) ^ bgcol;
-#elif BPP == 2
- ((uint32_t *)d)[0] = (dmask4[(font_data >> 6)] & xorcol) ^ bgcol;
- ((uint32_t *)d)[1] = (dmask4[(font_data >> 4) & 3] & xorcol) ^ bgcol;
- ((uint32_t *)d)[2] = (dmask4[(font_data >> 2) & 3] & xorcol) ^ bgcol;
- ((uint32_t *)d)[3] = (dmask4[(font_data >> 0) & 3] & xorcol) ^ bgcol;
-#else
- ((uint32_t *)d)[0] = (-((font_data >> 7)) & xorcol) ^ bgcol;
- ((uint32_t *)d)[1] = (-((font_data >> 6) & 1) & xorcol) ^ bgcol;
- ((uint32_t *)d)[2] = (-((font_data >> 5) & 1) & xorcol) ^ bgcol;
- ((uint32_t *)d)[3] = (-((font_data >> 4) & 1) & xorcol) ^ bgcol;
- ((uint32_t *)d)[4] = (-((font_data >> 3) & 1) & xorcol) ^ bgcol;
- ((uint32_t *)d)[5] = (-((font_data >> 2) & 1) & xorcol) ^ bgcol;
- ((uint32_t *)d)[6] = (-((font_data >> 1) & 1) & xorcol) ^ bgcol;
- ((uint32_t *)d)[7] = (-((font_data >> 0) & 1) & xorcol) ^ bgcol;
-#endif
-}
-
-static void glue(vga_draw_glyph8_, DEPTH)(uint8_t *d, int linesize,
- const uint8_t *font_ptr, int h,
- uint32_t fgcol, uint32_t bgcol)
-{
- uint32_t font_data, xorcol;
-
- xorcol = bgcol ^ fgcol;
- do {
- font_data = font_ptr[0];
- glue(vga_draw_glyph_line_, DEPTH)(d, font_data, xorcol, bgcol);
- font_ptr += 4;
- d += linesize;
- } while (--h);
-}
-
-static void glue(vga_draw_glyph16_, DEPTH)(uint8_t *d, int linesize,
- const uint8_t *font_ptr, int h,
- uint32_t fgcol, uint32_t bgcol)
-{
- uint32_t font_data, xorcol;
-
- xorcol = bgcol ^ fgcol;
- do {
- font_data = font_ptr[0];
- glue(vga_draw_glyph_line_, DEPTH)(d,
- expand4to8[font_data >> 4],
- xorcol, bgcol);
- glue(vga_draw_glyph_line_, DEPTH)(d + 8 * BPP,
- expand4to8[font_data & 0x0f],
- xorcol, bgcol);
- font_ptr += 4;
- d += linesize;
- } while (--h);
-}
-
-static void glue(vga_draw_glyph9_, DEPTH)(uint8_t *d, int linesize,
- const uint8_t *font_ptr, int h,
- uint32_t fgcol, uint32_t bgcol, int dup9)
-{
- uint32_t font_data, xorcol, v;
-
- xorcol = bgcol ^ fgcol;
- do {
- font_data = font_ptr[0];
-#if BPP == 1
- cpu_to_32wu((uint32_t *)d, (dmask16[(font_data >> 4)] & xorcol) ^ bgcol);
- v = (dmask16[(font_data >> 0) & 0xf] & xorcol) ^ bgcol;
- cpu_to_32wu(((uint32_t *)d)+1, v);
- if (dup9)
- ((uint8_t *)d)[8] = v >> (24 * (1 - BIG));
- else
- ((uint8_t *)d)[8] = bgcol;
-
-#elif BPP == 2
- cpu_to_32wu(((uint32_t *)d)+0, (dmask4[(font_data >> 6)] & xorcol) ^ bgcol);
- cpu_to_32wu(((uint32_t *)d)+1, (dmask4[(font_data >> 4) & 3] & xorcol) ^ bgcol);
- cpu_to_32wu(((uint32_t *)d)+2, (dmask4[(font_data >> 2) & 3] & xorcol) ^ bgcol);
- v = (dmask4[(font_data >> 0) & 3] & xorcol) ^ bgcol;
- cpu_to_32wu(((uint32_t *)d)+3, v);
- if (dup9)
- ((uint16_t *)d)[8] = v >> (16 * (1 - BIG));
- else
- ((uint16_t *)d)[8] = bgcol;
-#else
- ((uint32_t *)d)[0] = (-((font_data >> 7)) & xorcol) ^ bgcol;
- ((uint32_t *)d)[1] = (-((font_data >> 6) & 1) & xorcol) ^ bgcol;
- ((uint32_t *)d)[2] = (-((font_data >> 5) & 1) & xorcol) ^ bgcol;
- ((uint32_t *)d)[3] = (-((font_data >> 4) & 1) & xorcol) ^ bgcol;
- ((uint32_t *)d)[4] = (-((font_data >> 3) & 1) & xorcol) ^ bgcol;
- ((uint32_t *)d)[5] = (-((font_data >> 2) & 1) & xorcol) ^ bgcol;
- ((uint32_t *)d)[6] = (-((font_data >> 1) & 1) & xorcol) ^ bgcol;
- v = (-((font_data >> 0) & 1) & xorcol) ^ bgcol;
- ((uint32_t *)d)[7] = v;
- if (dup9)
- ((uint32_t *)d)[8] = v;
- else
- ((uint32_t *)d)[8] = bgcol;
-#endif
- font_ptr += 4;
- d += linesize;
- } while (--h);
-}
-
-/*
- * 4 color mode
- */
-static void glue(vga_draw_line2_, DEPTH)(VGAState *s1, uint8_t *d,
- const uint8_t *s, int width)
-{
- uint32_t plane_mask, *palette, data, v;
- int x;
-
- palette = s1->last_palette;
- plane_mask = mask16[s1->ar[0x12] & 0xf];
- width >>= 3;
- for(x = 0; x < width; x++) {
- data = ((uint32_t *)s)[0];
- data &= plane_mask;
- v = expand2[GET_PLANE(data, 0)];
- v |= expand2[GET_PLANE(data, 2)] << 2;
- ((PIXEL_TYPE *)d)[0] = palette[v >> 12];
- ((PIXEL_TYPE *)d)[1] = palette[(v >> 8) & 0xf];
- ((PIXEL_TYPE *)d)[2] = palette[(v >> 4) & 0xf];
- ((PIXEL_TYPE *)d)[3] = palette[(v >> 0) & 0xf];
-
- v = expand2[GET_PLANE(data, 1)];
- v |= expand2[GET_PLANE(data, 3)] << 2;
- ((PIXEL_TYPE *)d)[4] = palette[v >> 12];
- ((PIXEL_TYPE *)d)[5] = palette[(v >> 8) & 0xf];
- ((PIXEL_TYPE *)d)[6] = palette[(v >> 4) & 0xf];
- ((PIXEL_TYPE *)d)[7] = palette[(v >> 0) & 0xf];
- d += BPP * 8;
- s += 4;
- }
-}
-
-#if BPP == 1
-#define PUT_PIXEL2(d, n, v) ((uint16_t *)d)[(n)] = (v)
-#elif BPP == 2
-#define PUT_PIXEL2(d, n, v) ((uint32_t *)d)[(n)] = (v)
-#else
-#define PUT_PIXEL2(d, n, v) \
-((uint32_t *)d)[2*(n)] = ((uint32_t *)d)[2*(n)+1] = (v)
-#endif
-
-/*
- * 4 color mode, dup2 horizontal
- */
-static void glue(vga_draw_line2d2_, DEPTH)(VGAState *s1, uint8_t *d,
- const uint8_t *s, int width)
-{
- uint32_t plane_mask, *palette, data, v;
- int x;
-
- palette = s1->last_palette;
- plane_mask = mask16[s1->ar[0x12] & 0xf];
- width >>= 3;
- for(x = 0; x < width; x++) {
- data = ((uint32_t *)s)[0];
- data &= plane_mask;
- v = expand2[GET_PLANE(data, 0)];
- v |= expand2[GET_PLANE(data, 2)] << 2;
- PUT_PIXEL2(d, 0, palette[v >> 12]);
- PUT_PIXEL2(d, 1, palette[(v >> 8) & 0xf]);
- PUT_PIXEL2(d, 2, palette[(v >> 4) & 0xf]);
- PUT_PIXEL2(d, 3, palette[(v >> 0) & 0xf]);
-
- v = expand2[GET_PLANE(data, 1)];
- v |= expand2[GET_PLANE(data, 3)] << 2;
- PUT_PIXEL2(d, 4, palette[v >> 12]);
- PUT_PIXEL2(d, 5, palette[(v >> 8) & 0xf]);
- PUT_PIXEL2(d, 6, palette[(v >> 4) & 0xf]);
- PUT_PIXEL2(d, 7, palette[(v >> 0) & 0xf]);
- d += BPP * 16;
- s += 4;
- }
-}
-
-/*
- * 16 color mode
- */
-static void glue(vga_draw_line4_, DEPTH)(VGAState *s1, uint8_t *d,
- const uint8_t *s, int width)
-{
- uint32_t plane_mask, data, v, *palette;
- int x;
-
- palette = s1->last_palette;
- plane_mask = mask16[s1->ar[0x12] & 0xf];
- width >>= 3;
- for(x = 0; x < width; x++) {
- data = ((uint32_t *)s)[0];
- data &= plane_mask;
- v = expand4[GET_PLANE(data, 0)];
- v |= expand4[GET_PLANE(data, 1)] << 1;
- v |= expand4[GET_PLANE(data, 2)] << 2;
- v |= expand4[GET_PLANE(data, 3)] << 3;
- ((PIXEL_TYPE *)d)[0] = palette[v >> 28];
- ((PIXEL_TYPE *)d)[1] = palette[(v >> 24) & 0xf];
- ((PIXEL_TYPE *)d)[2] = palette[(v >> 20) & 0xf];
- ((PIXEL_TYPE *)d)[3] = palette[(v >> 16) & 0xf];
- ((PIXEL_TYPE *)d)[4] = palette[(v >> 12) & 0xf];
- ((PIXEL_TYPE *)d)[5] = palette[(v >> 8) & 0xf];
- ((PIXEL_TYPE *)d)[6] = palette[(v >> 4) & 0xf];
- ((PIXEL_TYPE *)d)[7] = palette[(v >> 0) & 0xf];
- d += BPP * 8;
- s += 4;
- }
-}
-
-/*
- * 16 color mode, dup2 horizontal
- */
-static void glue(vga_draw_line4d2_, DEPTH)(VGAState *s1, uint8_t *d,
- const uint8_t *s, int width)
-{
- uint32_t plane_mask, data, v, *palette;
- int x;
-
- palette = s1->last_palette;
- plane_mask = mask16[s1->ar[0x12] & 0xf];
- width >>= 3;
- for(x = 0; x < width; x++) {
- data = ((uint32_t *)s)[0];
- data &= plane_mask;
- v = expand4[GET_PLANE(data, 0)];
- v |= expand4[GET_PLANE(data, 1)] << 1;
- v |= expand4[GET_PLANE(data, 2)] << 2;
- v |= expand4[GET_PLANE(data, 3)] << 3;
- PUT_PIXEL2(d, 0, palette[v >> 28]);
- PUT_PIXEL2(d, 1, palette[(v >> 24) & 0xf]);
- PUT_PIXEL2(d, 2, palette[(v >> 20) & 0xf]);
- PUT_PIXEL2(d, 3, palette[(v >> 16) & 0xf]);
- PUT_PIXEL2(d, 4, palette[(v >> 12) & 0xf]);
- PUT_PIXEL2(d, 5, palette[(v >> 8) & 0xf]);
- PUT_PIXEL2(d, 6, palette[(v >> 4) & 0xf]);
- PUT_PIXEL2(d, 7, palette[(v >> 0) & 0xf]);
- d += BPP * 16;
- s += 4;
- }
-}
-
-/*
- * 256 color mode, double pixels
- *
- * XXX: add plane_mask support (never used in standard VGA modes)
- */
-static void glue(vga_draw_line8d2_, DEPTH)(VGAState *s1, uint8_t *d,
- const uint8_t *s, int width)
-{
- uint32_t *palette;
- int x;
-
- palette = s1->last_palette;
- width >>= 3;
- for(x = 0; x < width; x++) {
- PUT_PIXEL2(d, 0, palette[s[0]]);
- PUT_PIXEL2(d, 1, palette[s[1]]);
- PUT_PIXEL2(d, 2, palette[s[2]]);
- PUT_PIXEL2(d, 3, palette[s[3]]);
- d += BPP * 8;
- s += 4;
- }
-}
-
-/*
- * standard 256 color mode
- *
- * XXX: add plane_mask support (never used in standard VGA modes)
- */
-static void glue(vga_draw_line8_, DEPTH)(VGAState *s1, uint8_t *d,
- const uint8_t *s, int width)
-{
- uint32_t *palette;
- int x;
-
- palette = s1->last_palette;
- width >>= 3;
- for(x = 0; x < width; x++) {
- ((PIXEL_TYPE *)d)[0] = palette[s[0]];
- ((PIXEL_TYPE *)d)[1] = palette[s[1]];
- ((PIXEL_TYPE *)d)[2] = palette[s[2]];
- ((PIXEL_TYPE *)d)[3] = palette[s[3]];
- ((PIXEL_TYPE *)d)[4] = palette[s[4]];
- ((PIXEL_TYPE *)d)[5] = palette[s[5]];
- ((PIXEL_TYPE *)d)[6] = palette[s[6]];
- ((PIXEL_TYPE *)d)[7] = palette[s[7]];
- d += BPP * 8;
- s += 8;
- }
-}
-
-#endif /* DEPTH != 15 */
-
-
-/* XXX: optimize */
-
-/*
- * 15 bit color
- */
-static void glue(vga_draw_line15_, DEPTH)(VGAState *s1, uint8_t *d,
- const uint8_t *s, int width)
-{
-#if DEPTH == 15 && defined(WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN)
- memcpy(d, s, width * 2);
-#else
- int w;
- uint32_t v, r, g, b;
-
- w = width;
- do {
- v = lduw_raw((void *)s);
- r = (v >> 7) & 0xf8;
- g = (v >> 2) & 0xf8;
- b = (v << 3) & 0xf8;
- ((PIXEL_TYPE *)d)[0] = glue(rgb_to_pixel, DEPTH)(r, g, b);
- s += 2;
- d += BPP;
- } while (--w != 0);
-#endif
-}
-
-/*
- * 16 bit color
- */
-static void glue(vga_draw_line16_, DEPTH)(VGAState *s1, uint8_t *d,
- const uint8_t *s, int width)
-{
-#if DEPTH == 16 && defined(WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN)
- memcpy(d, s, width * 2);
-#else
- int w;
- uint32_t v, r, g, b;
-
- w = width;
- do {
- v = lduw_raw((void *)s);
- r = (v >> 8) & 0xf8;
- g = (v >> 3) & 0xfc;
- b = (v << 3) & 0xf8;
- ((PIXEL_TYPE *)d)[0] = glue(rgb_to_pixel, DEPTH)(r, g, b);
- s += 2;
- d += BPP;
- } while (--w != 0);
-#endif
-}
-
-/*
- * 24 bit color
- */
-static void glue(vga_draw_line24_, DEPTH)(VGAState *s1, uint8_t *d,
- const uint8_t *s, int width)
-{
- int w;
- uint32_t r, g, b;
-
- w = width;
- do {
-#if defined(TARGET_WORDS_BIGENDIAN)
- r = s[0];
- g = s[1];
- b = s[2];
-#else
- b = s[0];
- g = s[1];
- r = s[2];
-#endif
- ((PIXEL_TYPE *)d)[0] = glue(rgb_to_pixel, DEPTH)(r, g, b);
- s += 3;
- d += BPP;
- } while (--w != 0);
-}
-
-/*
- * 32 bit color
- */
-static void glue(vga_draw_line32_, DEPTH)(VGAState *s1, uint8_t *d,
- const uint8_t *s, int width)
-{
-#if DEPTH == 32 && defined(WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN)
- memcpy(d, s, width * 4);
-#else
- int w;
- uint32_t r, g, b;
-
- w = width;
- do {
-#if defined(TARGET_WORDS_BIGENDIAN)
- r = s[1];
- g = s[2];
- b = s[3];
-#else
- b = s[0];
- g = s[1];
- r = s[2];
-#endif
- ((PIXEL_TYPE *)d)[0] = glue(rgb_to_pixel, DEPTH)(r, g, b);
- s += 4;
- d += BPP;
- } while (--w != 0);
-#endif
-}
-
-#if DEPTH != 15
-void glue(vga_draw_cursor_line_, DEPTH)(uint8_t *d1,
- const uint8_t *src1,
- int poffset, int w,
- unsigned int color0,
- unsigned int color1,
- unsigned int color_xor)
-{
- const uint8_t *plane0, *plane1;
- int x, b0, b1;
- uint8_t *d;
-
- d = d1;
- plane0 = src1;
- plane1 = src1 + poffset;
- for(x = 0; x < w; x++) {
- b0 = (plane0[x >> 3] >> (7 - (x & 7))) & 1;
- b1 = (plane1[x >> 3] >> (7 - (x & 7))) & 1;
-#if DEPTH == 8
- switch(b0 | (b1 << 1)) {
- case 0:
- break;
- case 1:
- d[0] ^= color_xor;
- break;
- case 2:
- d[0] = color0;
- break;
- case 3:
- d[0] = color1;
- break;
- }
-#elif DEPTH == 16
- switch(b0 | (b1 << 1)) {
- case 0:
- break;
- case 1:
- ((uint16_t *)d)[0] ^= color_xor;
- break;
- case 2:
- ((uint16_t *)d)[0] = color0;
- break;
- case 3:
- ((uint16_t *)d)[0] = color1;
- break;
- }
-#elif DEPTH == 32
- switch(b0 | (b1 << 1)) {
- case 0:
- break;
- case 1:
- ((uint32_t *)d)[0] ^= color_xor;
- break;
- case 2:
- ((uint32_t *)d)[0] = color0;
- break;
- case 3:
- ((uint32_t *)d)[0] = color1;
- break;
- }
-#else
-#error unsupported depth
-#endif
- d += BPP;
- }
-}
-#endif
-
-#undef PUT_PIXEL2
-#undef DEPTH
-#undef BPP
-#undef PIXEL_TYPE
+++ /dev/null
-#ifndef IA64_INTRINSIC_H
-#define IA64_INTRINSIC_H
-
-/*
- * Compiler-dependent Intrinsics
- *
- * Copyright (C) 2002,2003 Jun Nakajima <jun.nakajima@intel.com>
- * Copyright (C) 2002,2003 Suresh Siddha <suresh.b.siddha@intel.com>
- *
- */
-extern long ia64_cmpxchg_called_with_bad_pointer (void);
-extern void ia64_bad_param_for_getreg (void);
-#define ia64_cmpxchg(sem,ptr,o,n,s) ({ \
- uint64_t _o, _r; \
- switch(s) { \
- case 1: _o = (uint8_t)(long)(o); break; \
- case 2: _o = (uint16_t)(long)(o); break; \
- case 4: _o = (uint32_t)(long)(o); break; \
- case 8: _o = (uint64_t)(long)(o); break; \
- default: break; \
- } \
- switch(s) { \
- case 1: \
- _r = ia64_cmpxchg1_##sem((uint8_t*)ptr,n,_o); break; \
- case 2: \
- _r = ia64_cmpxchg2_##sem((uint16_t*)ptr,n,_o); break; \
- case 4: \
- _r = ia64_cmpxchg4_##sem((uint32_t*)ptr,n,_o); break; \
- case 8: \
- _r = ia64_cmpxchg8_##sem((uint64_t*)ptr,n,_o); break; \
- default: \
- _r = ia64_cmpxchg_called_with_bad_pointer(); break; \
- } \
- (__typeof__(o)) _r; \
-})
-
-#define cmpxchg_acq(ptr,o,n) ia64_cmpxchg(acq,ptr,o,n,sizeof(*ptr))
-#define cmpxchg_rel(ptr,o,n) ia64_cmpxchg(rel,ptr,o,n,sizeof(*ptr))
-
-/*
- * Register Names for getreg() and setreg().
- *
- * The "magic" numbers happen to match the values used by the Intel compiler's
- * getreg()/setreg() intrinsics.
- */
-
-/* Special Registers */
-
-#define _IA64_REG_IP 1016 /* getreg only */
-#define _IA64_REG_PSR 1019
-#define _IA64_REG_PSR_L 1019
-
-/* General Integer Registers */
-
-#define _IA64_REG_GP 1025 /* R1 */
-#define _IA64_REG_R8 1032 /* R8 */
-#define _IA64_REG_R9 1033 /* R9 */
-#define _IA64_REG_SP 1036 /* R12 */
-#define _IA64_REG_TP 1037 /* R13 */
-
-/* Application Registers */
-
-#define _IA64_REG_AR_KR0 3072
-#define _IA64_REG_AR_KR1 3073
-#define _IA64_REG_AR_KR2 3074
-#define _IA64_REG_AR_KR3 3075
-#define _IA64_REG_AR_KR4 3076
-#define _IA64_REG_AR_KR5 3077
-#define _IA64_REG_AR_KR6 3078
-#define _IA64_REG_AR_KR7 3079
-#define _IA64_REG_AR_RSC 3088
-#define _IA64_REG_AR_BSP 3089
-#define _IA64_REG_AR_BSPSTORE 3090
-#define _IA64_REG_AR_RNAT 3091
-#define _IA64_REG_AR_FCR 3093
-#define _IA64_REG_AR_EFLAG 3096
-#define _IA64_REG_AR_CSD 3097
-#define _IA64_REG_AR_SSD 3098
-#define _IA64_REG_AR_CFLAG 3099
-#define _IA64_REG_AR_FSR 3100
-#define _IA64_REG_AR_FIR 3101
-#define _IA64_REG_AR_FDR 3102
-#define _IA64_REG_AR_CCV 3104
-#define _IA64_REG_AR_UNAT 3108
-#define _IA64_REG_AR_FPSR 3112
-#define _IA64_REG_AR_ITC 3116
-#define _IA64_REG_AR_PFS 3136
-#define _IA64_REG_AR_LC 3137
-#define _IA64_REG_AR_EC 3138
-
-/* Control Registers */
-
-#define _IA64_REG_CR_DCR 4096
-#define _IA64_REG_CR_ITM 4097
-#define _IA64_REG_CR_IVA 4098
-#define _IA64_REG_CR_PTA 4104
-#define _IA64_REG_CR_IPSR 4112
-#define _IA64_REG_CR_ISR 4113
-#define _IA64_REG_CR_IIP 4115
-#define _IA64_REG_CR_IFA 4116
-#define _IA64_REG_CR_ITIR 4117
-#define _IA64_REG_CR_IIPA 4118
-#define _IA64_REG_CR_IFS 4119
-#define _IA64_REG_CR_IIM 4120
-#define _IA64_REG_CR_IHA 4121
-#define _IA64_REG_CR_LID 4160
-#define _IA64_REG_CR_IVR 4161 /* getreg only */
-#define _IA64_REG_CR_TPR 4162
-#define _IA64_REG_CR_EOI 4163
-#define _IA64_REG_CR_IRR0 4164 /* getreg only */
-#define _IA64_REG_CR_IRR1 4165 /* getreg only */
-#define _IA64_REG_CR_IRR2 4166 /* getreg only */
-#define _IA64_REG_CR_IRR3 4167 /* getreg only */
-#define _IA64_REG_CR_ITV 4168
-#define _IA64_REG_CR_PMV 4169
-#define _IA64_REG_CR_CMCV 4170
-#define _IA64_REG_CR_LRR0 4176
-#define _IA64_REG_CR_LRR1 4177
-
-/* Indirect Registers for getindreg() and setindreg() */
-
-#define _IA64_REG_INDR_CPUID 9000 /* getindreg only */
-#define _IA64_REG_INDR_DBR 9001
-#define _IA64_REG_INDR_IBR 9002
-#define _IA64_REG_INDR_PKR 9003
-#define _IA64_REG_INDR_PMC 9004
-#define _IA64_REG_INDR_PMD 9005
-#define _IA64_REG_INDR_RR 9006
-
-#ifdef __INTEL_COMPILER
-void __fc(uint64_t *addr);
-void __synci(void);
-void __isrlz(void);
-void __dsrlz(void);
-uint64_t __getReg(const int whichReg);
-uint64_t _InterlockedCompareExchange8_rel(volatile uint8_t *dest, uint64_t xchg, uint64_t comp);
-uint64_t _InterlockedCompareExchange8_acq(volatile uint8_t *dest, uint64_t xchg, uint64_t comp);
-uint64_t _InterlockedCompareExchange16_rel(volatile uint16_t *dest, uint64_t xchg, uint64_t comp);
-uint64_t _InterlockedCompareExchange16_acq(volatile uint16_t *dest, uint64_t xchg, uint64_t comp);
-uint64_t _InterlockedCompareExchange_rel(volatile uint32_t *dest, uint64_t xchg, uint64_t comp);
-uint64_t _InterlockedCompareExchange_acq(volatile uint32_t *dest, uint64_t xchg, uint64_t comp);
-uint64_t _InterlockedCompareExchange64_rel(volatile uint64_t *dest, uint64_t xchg, uint64_t comp);
-u64_t _InterlockedCompareExchange64_acq(volatile uint64_t *dest, uint64_t xchg, uint64_t comp);
-
-#define ia64_cmpxchg1_rel _InterlockedCompareExchange8_rel
-#define ia64_cmpxchg1_acq _InterlockedCompareExchange8_acq
-#define ia64_cmpxchg2_rel _InterlockedCompareExchange16_rel
-#define ia64_cmpxchg2_acq _InterlockedCompareExchange16_acq
-#define ia64_cmpxchg4_rel _InterlockedCompareExchange_rel
-#define ia64_cmpxchg4_acq _InterlockedCompareExchange_acq
-#define ia64_cmpxchg8_rel _InterlockedCompareExchange64_rel
-#define ia64_cmpxchg8_acq _InterlockedCompareExchange64_acq
-
-#define ia64_srlz_d __dsrlz
-#define ia64_srlz_i __isrlz
-#define __ia64_fc __fc
-#define ia64_sync_i __synci
-#define __ia64_getreg __getReg
-#else /* __INTEL_COMPILER */
-#define ia64_cmpxchg1_acq(ptr, new, old) \
-({ \
- uint64_t ia64_intri_res; \
- asm volatile ("mov ar.ccv=%0;;" :: "rO"(old)); \
- asm volatile ("cmpxchg1.acq %0=[%1],%2,ar.ccv": \
- "=r"(ia64_intri_res) : "r"(ptr), "r"(new) : "memory"); \
- ia64_intri_res; \
-})
-
-#define ia64_cmpxchg1_rel(ptr, new, old) \
-({ \
- uint64_t ia64_intri_res; \
- asm volatile ("mov ar.ccv=%0;;" :: "rO"(old)); \
- asm volatile ("cmpxchg1.rel %0=[%1],%2,ar.ccv": \
- "=r"(ia64_intri_res) : "r"(ptr), "r"(new) : "memory"); \
- ia64_intri_res; \
-})
-
-#define ia64_cmpxchg2_acq(ptr, new, old) \
-({ \
- uint64_t ia64_intri_res; \
- asm volatile ("mov ar.ccv=%0;;" :: "rO"(old)); \
- asm volatile ("cmpxchg2.acq %0=[%1],%2,ar.ccv": \
- "=r"(ia64_intri_res) : "r"(ptr), "r"(new) : "memory"); \
- ia64_intri_res; \
-})
-
-#define ia64_cmpxchg2_rel(ptr, new, old) \
-({ \
- uint64_t ia64_intri_res; \
- asm volatile ("mov ar.ccv=%0;;" :: "rO"(old)); \
- \
- asm volatile ("cmpxchg2.rel %0=[%1],%2,ar.ccv": \
- "=r"(ia64_intri_res) : "r"(ptr), "r"(new) : "memory"); \
- ia64_intri_res; \
-})
-
-#define ia64_cmpxchg4_acq(ptr, new, old) \
-({ \
- uint64_t ia64_intri_res; \
- asm volatile ("mov ar.ccv=%0;;" :: "rO"(old)); \
- asm volatile ("cmpxchg4.acq %0=[%1],%2,ar.ccv": \
- "=r"(ia64_intri_res) : "r"(ptr), "r"(new) : "memory"); \
- ia64_intri_res; \
-})
-
-#define ia64_cmpxchg4_rel(ptr, new, old) \
-({ \
- uint64_t ia64_intri_res; \
- asm volatile ("mov ar.ccv=%0;;" :: "rO"(old)); \
- asm volatile ("cmpxchg4.rel %0=[%1],%2,ar.ccv": \
- "=r"(ia64_intri_res) : "r"(ptr), "r"(new) : "memory"); \
- ia64_intri_res; \
-})
-
-#define ia64_cmpxchg8_acq(ptr, new, old) \
-({ \
- uint64_t ia64_intri_res; \
- asm volatile ("mov ar.ccv=%0;;" :: "rO"(old)); \
- asm volatile ("cmpxchg8.acq %0=[%1],%2,ar.ccv": \
- "=r"(ia64_intri_res) : "r"(ptr), "r"(new) : "memory"); \
- ia64_intri_res; \
-})
-
-#define ia64_cmpxchg8_rel(ptr, new, old) \
-({ \
- uint64_t ia64_intri_res; \
- asm volatile ("mov ar.ccv=%0;;" :: "rO"(old)); \
- \
- asm volatile ("cmpxchg8.rel %0=[%1],%2,ar.ccv": \
- "=r"(ia64_intri_res) : "r"(ptr), "r"(new) : "memory"); \
- ia64_intri_res; \
-})
-
-#define ia64_srlz_i() asm volatile (";; srlz.i ;;" ::: "memory")
-#define ia64_srlz_d() asm volatile (";; srlz.d" ::: "memory");
-#define __ia64_fc(addr) asm volatile ("fc %0" :: "r"(addr) : "memory")
-#define ia64_sync_i() asm volatile (";; sync.i" ::: "memory")
-
-register unsigned long ia64_r13 asm ("r13") __attribute_used__;
-#define __ia64_getreg(regnum) \
-({ \
- uint64_t ia64_intri_res; \
- \
- switch (regnum) { \
- case _IA64_REG_GP: \
- asm volatile ("mov %0=gp" : "=r"(ia64_intri_res)); \
- break; \
- case _IA64_REG_IP: \
- asm volatile ("mov %0=ip" : "=r"(ia64_intri_res)); \
- break; \
- case _IA64_REG_PSR: \
- asm volatile ("mov %0=psr" : "=r"(ia64_intri_res)); \
- break; \
- case _IA64_REG_TP: /* for current() */ \
- ia64_intri_res = ia64_r13; \
- break; \
- case _IA64_REG_AR_KR0 ... _IA64_REG_AR_EC: \
- asm volatile ("mov %0=ar%1" : "=r" (ia64_intri_res) \
- : "i"(regnum - _IA64_REG_AR_KR0)); \
- break; \
- case _IA64_REG_CR_DCR ... _IA64_REG_CR_LRR1: \
- asm volatile ("mov %0=cr%1" : "=r" (ia64_intri_res) \
- : "i" (regnum - _IA64_REG_CR_DCR)); \
- break; \
- case _IA64_REG_SP: \
- asm volatile ("mov %0=sp" : "=r" (ia64_intri_res)); \
- break; \
- default: \
- ia64_bad_param_for_getreg(); \
- break; \
- } \
- ia64_intri_res; \
-})
-
-#endif /* __INTEL_COMPILER */
-#endif /* IA64_INTRINSIC_H */
+++ /dev/null
-/*
- * QEMU keylayout reader: read rdesktop style keylaouts
- *
- * Copyright (c) 2004,2005 Johannes E. Schindelin
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include <ctype.h>
-
-#ifdef KEYBOARD_IGNORE_CASE
-#define STRCMP strcasecmp
-#else
-#define STRCMP strcmp
-#endif
-
-/* binary search through nameToKeysym */
-static int get_keysym(const char* name)
-{
- int i1=-1,i2=sizeof(name2keysym)/sizeof(name2keysym_t),i3=i2/2,r;
- while((r=STRCMP(name,name2keysym[i3].name))!=0) {
- if(r<0)
- i2=i3;
- else
- i1=i3;
- i3=(i1+i2)/2;
- if(i2-i1<2)
- return 0;
- }
- return name2keysym[i3].keysym;
-}
-
-typedef unsigned short WORD;
-#define MAX_NORMAL_KEYCODE 512
-#define MAX_EXTRA_COUNT 256
-typedef struct {
- WORD keysym2keycode[MAX_NORMAL_KEYCODE];
- struct {
- int keysym;
- WORD keycode;
- } keysym2keycode_extra[MAX_EXTRA_COUNT];
- int extra_count;
-} kbd_layout_t;
-
-static int parse_int(const char* text)
-{
- if(!strncmp(text,"0x",2)) {
- int result=0;
- sscanf(text+2,"%x",&result);
- return result;
- }
- return atoi(text);
-}
-
-static kbd_layout_t* parse_keyboard_layout(const char* language,kbd_layout_t* k)
-{
- FILE* f;
- const char* prefix="/keymaps/";
- char* file_name=malloc(strlen(prefix)+strlen(language)+strlen(bios_dir)+1);
-
- if(!k)
- k=calloc(1, sizeof(kbd_layout_t));
- strcpy(file_name,bios_dir);
- strcat(file_name,prefix);
- strcat(file_name,language);
- if(file_name[strlen(file_name)-1]=='\n')
- file_name[strlen(file_name)-1]=0;
- if(!(f=fopen(file_name,"r"))) {
- term_printf("Warning: could not read keymap - falling back native keycodes!\n");
- free(file_name);
- return 0;
- }
- free(file_name);
- while(!feof(f)) {
- char line[1024];
- fgets(line,1024,f);
- if(line[0]=='#')
- continue;
- if(!strncmp(line,"map ",4))
- continue;
- if(!strncmp(line,"include ",8))
- parse_keyboard_layout(line+8,k);
- else {
- char* end_of_keysym=line;
- while(*end_of_keysym!=0 && *end_of_keysym!=' ')
- end_of_keysym++;
- if(*end_of_keysym) {
- int keysym;
- *end_of_keysym=0;
- keysym=get_keysym(line);
- if(keysym==0) {
- term_printf("Warning: 1unknown keysym %s\n",line);
- } else {
- const char* rest=end_of_keysym+1;
- int keycode=parse_int(rest);
- /* if(keycode&0x80)
- keycode=(keycode<<8)^0x80e0; */
- if(keysym<MAX_NORMAL_KEYCODE) {
- //term_printf("Setting keysym %s (%d) to %d\n",line,keysym,keycode);
- k->keysym2keycode[keysym]=keycode;
-#ifndef KEYBOARD_IGNORE_CASE
- line[0]=toupper(line[0]);
- keysym=get_keysym(line);
- if(keysym)
- k->keysym2keycode[keysym]=keycode;
-#endif
- } else {
- if(k->extra_count>=MAX_EXTRA_COUNT) {
- term_printf("Warning: Could not assign keysym %s (0x%x) because of memory constraints.\n",line,keysym);
- } else {
- //term_printf("Setting %d: %d,%d\n",k->extra_count,keysym,keycode);
- k->keysym2keycode_extra[k->extra_count].keysym=keysym;
- k->keysym2keycode_extra[k->extra_count].keycode=keycode;
- k->extra_count++;
- }
- }
- }
- }
- }
- }
- fclose(f);
- return k;
-}
-
-static void* init_keyboard_layout(const char* language)
-{
- return parse_keyboard_layout(language,0);
-}
-
-static WORD keysym2scancode(void* kbd_layout, int keysym)
-{
- kbd_layout_t* k=kbd_layout;
- if(keysym<MAX_NORMAL_KEYCODE) {
- if(k->keysym2keycode[keysym]==0)
- term_printf("Warning: no scancode found for keysym %d\n",keysym);
- return k->keysym2keycode[keysym];
- } else {
- int i;
-#ifdef XK_ISO_Left_Tab
- if(keysym==XK_ISO_Left_Tab)
- keysym=XK_Tab;
-#endif
- for(i=0;i<k->extra_count;i++)
- if(k->keysym2keycode_extra[i].keysym==keysym)
- return k->keysym2keycode_extra[i].keycode;
- }
- return 0;
-}
-
+++ /dev/null
-# generated from XKB map ar
-include common
-map 0x401
-exclam 0x02 shift
-at 0x03 shift
-numbersign 0x04 shift
-dollar 0x05 shift
-percent 0x06 shift
-asciicircum 0x07 shift
-ampersand 0x08 shift
-asterisk 0x09 shift
-parenleft 0x0a shift
-parenright 0x0b shift
-minus 0x0c
-underscore 0x0c shift
-equal 0x0d
-plus 0x0d shift
-Arabic_dad 0x10 altgr
-Arabic_fatha 0x10 shift altgr
-Arabic_sad 0x11 altgr
-Arabic_fathatan 0x11 shift altgr
-Arabic_theh 0x12 altgr
-Arabic_damma 0x12 shift altgr
-Arabic_qaf 0x13 altgr
-Arabic_dammatan 0x13 shift altgr
-Arabic_feh 0x14 altgr
-UFEF9 0x14 shift altgr
-Arabic_ghain 0x15 altgr
-Arabic_hamzaunderalef 0x15 shift altgr
-Arabic_ain 0x16 altgr
-grave 0x16 shift altgr
-Arabic_ha 0x17 altgr
-division 0x17 shift altgr
-Arabic_khah 0x18 altgr
-multiply 0x18 shift altgr
-Arabic_hah 0x19 altgr
-Arabic_semicolon 0x19 shift altgr
-bracketleft 0x1a
-braceleft 0x1a shift
-Arabic_jeem 0x1a altgr
-bracketright 0x1b
-braceright 0x1b shift
-Arabic_dal 0x1b altgr
-Arabic_sheen 0x1e altgr
-backslash 0x1e shift altgr
-Arabic_seen 0x1f altgr
-Arabic_yeh 0x20 altgr
-bracketleft 0x20 shift altgr
-Arabic_beh 0x21 altgr
-bracketright 0x21 shift altgr
-Arabic_lam 0x22 altgr
-UFEF7 0x22 shift altgr
-Arabic_alef 0x23 altgr
-Arabic_hamzaonalef 0x23 shift altgr
-Arabic_teh 0x24 altgr
-Arabic_tatweel 0x24 shift altgr
-Arabic_noon 0x25 altgr
-Arabic_comma 0x25 shift altgr
-Arabic_meem 0x26 altgr
-slash 0x26 shift altgr
-semicolon 0x27
-colon 0x27 shift
-Arabic_kaf 0x27 altgr
-apostrophe 0x28
-quotedbl 0x28 shift
-Arabic_tah 0x28 altgr
-grave 0x29
-asciitilde 0x29 shift
-Arabic_thal 0x29 altgr
-Arabic_shadda 0x29 shift altgr
-backslash 0x2b
-bar 0x2b shift
-less 0x2b altgr
-greater 0x2b shift altgr
-Arabic_hamzaonyeh 0x2c altgr
-asciitilde 0x2c shift altgr
-Arabic_hamza 0x2d altgr
-Arabic_sukun 0x2d shift altgr
-Arabic_hamzaonwaw 0x2e altgr
-Arabic_kasra 0x2e shift altgr
-Arabic_ra 0x2f altgr
-Arabic_kasratan 0x2f shift altgr
-UFEFB 0x30 altgr
-UFEF5 0x30 shift altgr
-Arabic_alefmaksura 0x31 altgr
-Arabic_maddaonalef 0x31 shift altgr
-Arabic_tehmarbuta 0x32 altgr
-apostrophe 0x32 shift altgr
-comma 0x33
-less 0x33 shift
-Arabic_waw 0x33 altgr
-period 0x34
-greater 0x34 shift
-Arabic_zain 0x34 altgr
-slash 0x35
-question 0x35 shift
-Arabic_zah 0x35 altgr
-Arabic_question_mark 0x35 shift altgr
+++ /dev/null
-include modifiers
-
-#
-# Top row
-#
-1 0x2
-2 0x3
-3 0x4
-4 0x5
-5 0x6
-6 0x7
-7 0x8
-8 0x9
-9 0xa
-0 0xb
-BackSpace 0xe
-
-#
-# QWERTY first row
-#
-Tab 0xf localstate
-ISO_Left_Tab 0xf shift
-q 0x10 addupper
-w 0x11 addupper
-e 0x12 addupper
-r 0x13 addupper
-t 0x14 addupper
-y 0x15 addupper
-u 0x16 addupper
-i 0x17 addupper
-o 0x18 addupper
-p 0x19 addupper
-
-#
-# QWERTY second row
-#
-a 0x1e addupper
-s 0x1f addupper
-d 0x20 addupper
-f 0x21 addupper
-g 0x22 addupper
-h 0x23 addupper
-j 0x24 addupper
-k 0x25 addupper
-l 0x26 addupper
-Return 0x1c localstate
-
-#
-# QWERTY third row
-#
-z 0x2c addupper
-x 0x2d addupper
-c 0x2e addupper
-v 0x2f addupper
-b 0x30 addupper
-n 0x31 addupper
-m 0x32 addupper
-
-space 0x39 localstate
-
-less 0x56
-greater 0x56 shift
-bar 0x56 altgr
-brokenbar 0x56 shift altgr
-
-#
-# Esc and Function keys
-#
-Escape 0x1 localstate
-F1 0x3b localstate
-F2 0x3c localstate
-F3 0x3d localstate
-F4 0x3e localstate
-F5 0x3f localstate
-F6 0x40 localstate
-F7 0x41 localstate
-F8 0x42 localstate
-F9 0x43 localstate
-F10 0x44 localstate
-F11 0x57 localstate
-F12 0x58 localstate
-
-# Printscreen, Scrollock and Pause
-# Printscreen really requires four scancodes (0xe0, 0x2a, 0xe0, 0x37),
-# but (0xe0, 0x37) seems to work.
-Print 0xb7 localstate
-Sys_Req 0xb7 localstate
-Execute 0xb7 localstate
-Scroll_Lock 0x46
-
-#
-# Insert - PgDown
-#
-Insert 0xd2 localstate
-Delete 0xd3 localstate
-Home 0xc7 localstate
-End 0xcf localstate
-Page_Up 0xc9 localstate
-Page_Down 0xd1 localstate
-
-#
-# Arrow keys
-#
-Left 0xcb localstate
-Up 0xc8 localstate
-Down 0xd0 localstate
-Right 0xcd localstate
-
-#
-# Numpad
-#
-Num_Lock 0x45
-KP_Divide 0xb5
-KP_Multiply 0x37
-KP_Subtract 0x4a
-KP_Add 0x4e
-KP_Enter 0x9c
-
-KP_Decimal 0x53 numlock
-KP_Separator 0x53 numlock
-KP_Delete 0x53
-
-KP_0 0x52 numlock
-KP_Insert 0x52
-
-KP_1 0x4f numlock
-KP_End 0x4f
-
-KP_2 0x50 numlock
-KP_Down 0x50
-
-KP_3 0x51 numlock
-KP_Next 0x51
-
-KP_4 0x4b numlock
-KP_Left 0x4b
-
-KP_5 0x4c numlock
-KP_Begin 0x4c
-
-KP_6 0x4d numlock
-KP_Right 0x4d
-
-KP_7 0x47 numlock
-KP_Home 0x47
-
-KP_8 0x48 numlock
-KP_Up 0x48
-
-KP_9 0x49 numlock
-KP_Prior 0x49
-
-Caps_Lock 0x3a
-#
-# Inhibited keys
-#
-Multi_key 0x0 inhibit
+++ /dev/null
-#!/usr/bin/env python2
-# -*-Python-*-
-#
-#
-# Copyright (C) 2001 Peter Åstrand <peter@cendio.se>
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; version 2 of the License.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-import sys
-
-def main():
- f = open(sys.argv[1])
- while 1:
- line = f.readline()
- if not line: break
-
- if line.startswith("#") or line.startswith("include"):
- print line,
- continue
-
- fields = line.split()
-
- if line.startswith("map"):
- print "map 0x%s" % fields[1]
- continue
-
- scancode = fields[0]
- for pos in range(1, len(fields)):
- keysym = fields[pos]
-
- if pos == 1:
- modifiers = ""
- elif pos == 2:
- modifiers = "shift"
- elif pos == 3:
- modifiers = "altgr"
- elif pos == 4:
- modifiers = "shift altgr"
- else:
- raise("Invalid line: %s" % line)
-
- print "%s 0x%s %s" % (keysym, scancode, modifiers)
-
-
-
-if __name__ == "__main__":
- if len(sys.argv) < 2:
- print "Convert old-style keymaps to new style"
- print "Usage: %s <old-style-keymap>" % sys.argv[0]
- sys.exit(1)
- else:
- main()
+++ /dev/null
-# generated from XKB map dk
-include common
-map 0x406
-exclam 0x02 shift
-exclamdown 0x02 altgr
-onesuperior 0x02 shift altgr
-quotedbl 0x03 shift
-at 0x03 altgr
-twosuperior 0x03 shift altgr
-numbersign 0x04 shift
-sterling 0x04 altgr
-threesuperior 0x04 shift altgr
-currency 0x05 shift
-dollar 0x05 altgr
-onequarter 0x05 shift altgr
-percent 0x06 shift
-onehalf 0x06 altgr
-cent 0x06 shift altgr
-ampersand 0x07 shift
-yen 0x07 altgr
-fiveeighths 0x07 shift altgr
-slash 0x08 shift
-braceleft 0x08 altgr
-division 0x08 shift altgr
-parenleft 0x09 shift
-bracketleft 0x09 altgr
-guillemotleft 0x09 shift altgr
-parenright 0x0a shift
-bracketright 0x0a altgr
-guillemotright 0x0a shift altgr
-equal 0x0b shift
-braceright 0x0b altgr
-degree 0x0b shift altgr
-plus 0x0c
-question 0x0c shift
-plusminus 0x0c altgr
-questiondown 0x0c shift altgr
-dead_acute 0x0d
-dead_grave 0x0d shift
-bar 0x0d altgr
-brokenbar 0x0d shift altgr
-Greek_OMEGA 0x10 shift altgr
-lstroke 0x11 altgr
-Lstroke 0x11 shift altgr
-EuroSign 0x12 altgr
-cent 0x12 shift altgr
-registered 0x13 altgr
-thorn 0x14 altgr
-THORN 0x14 shift altgr
-leftarrow 0x15 altgr
-yen 0x15 shift altgr
-downarrow 0x16 altgr
-uparrow 0x16 shift altgr
-rightarrow 0x17 altgr
-idotless 0x17 shift altgr
-oe 0x18 altgr
-OE 0x18 shift altgr
-thorn 0x19 altgr
-THORN 0x19 shift altgr
-aring 0x1a
-Aring 0x1a shift
-dead_diaeresis 0x1a altgr
-dead_abovering 0x1a shift altgr
-dead_diaeresis 0x1b
-dead_circumflex 0x1b shift
-dead_tilde 0x1b altgr
-dead_caron 0x1b shift altgr
-ordfeminine 0x1e altgr
-masculine 0x1e shift altgr
-ssharp 0x1f altgr
-section 0x1f shift altgr
-eth 0x20 altgr
-ETH 0x20 shift altgr
-dstroke 0x21 altgr
-ordfeminine 0x21 shift altgr
-eng 0x22 altgr
-ENG 0x22 shift altgr
-hstroke 0x23 altgr
-Hstroke 0x23 shift altgr
-kra 0x25 altgr
-lstroke 0x26 altgr
-Lstroke 0x26 shift altgr
-ae 0x27
-AE 0x27 shift
-oslash 0x28
-Ooblique 0x28 shift
-dead_caron 0x28 shift altgr
-onehalf 0x29
-section 0x29 shift
-threequarters 0x29 altgr
-paragraph 0x29 shift altgr
-apostrophe 0x2b
-asterisk 0x2b shift
-dead_doubleacute 0x2b altgr
-multiply 0x2b shift altgr
-guillemotleft 0x2c altgr
-guillemotright 0x2d altgr
-copyright 0x2e altgr
-leftdoublequotemark 0x2f altgr
-grave 0x2f shift altgr
-rightdoublequotemark 0x30 altgr
-mu 0x32 altgr
-masculine 0x32 shift altgr
-comma 0x33
-semicolon 0x33 shift
-dead_cedilla 0x33 altgr
-dead_ogonek 0x33 shift altgr
-period 0x34
-colon 0x34 shift
-periodcentered 0x34 altgr
-dead_abovedot 0x34 shift altgr
-minus 0x35
-underscore 0x35 shift
-hyphen 0x35 altgr
-macron 0x35 shift altgr
-nobreakspace 0x39 altgr
-less 0x56
-greater 0x56 shift
-backslash 0x56 altgr
-notsign 0x56 shift altgr
+++ /dev/null
-# generated from XKB map de
-include common
-map 0x407
-exclam 0x02 shift
-onesuperior 0x02 altgr
-exclamdown 0x02 shift altgr
-quotedbl 0x03 shift
-twosuperior 0x03 altgr
-oneeighth 0x03 shift altgr
-section 0x04 shift
-threesuperior 0x04 altgr
-sterling 0x04 shift altgr
-dollar 0x05 shift
-onequarter 0x05 altgr
-currency 0x05 shift altgr
-percent 0x06 shift
-onehalf 0x06 altgr
-threeeighths 0x06 shift altgr
-ampersand 0x07 shift
-threequarters 0x07 altgr
-fiveeighths 0x07 shift altgr
-slash 0x08 shift
-braceleft 0x08 altgr
-seveneighths 0x08 shift altgr
-parenleft 0x09 shift
-bracketleft 0x09 altgr
-trademark 0x09 shift altgr
-parenright 0x0a shift
-bracketright 0x0a altgr
-plusminus 0x0a shift altgr
-equal 0x0b shift
-braceright 0x0b altgr
-ssharp 0x0c
-question 0x0c shift
-backslash 0x0c altgr
-questiondown 0x0c shift altgr
-acute 0x0d
-dead_acute 0x0d
-grave 0x0d shift
-dead_grave 0x0d shift
-dead_cedilla 0x0d altgr
-dead_ogonek 0x0d shift altgr
-at 0x10 altgr
-Greek_OMEGA 0x10 shift altgr
-EuroSign 0x12 altgr
-paragraph 0x13 altgr
-registered 0x13 shift altgr
-tslash 0x14 altgr
-Tslash 0x14 shift altgr
-z 0x15 addupper
-leftarrow 0x15 altgr
-yen 0x15 shift altgr
-downarrow 0x16 altgr
-uparrow 0x16 shift altgr
-rightarrow 0x17 altgr
-idotless 0x17 shift altgr
-oslash 0x18 altgr
-Ooblique 0x18 shift altgr
-thorn 0x19 altgr
-THORN 0x19 shift altgr
-udiaeresis 0x1a
-Udiaeresis 0x1a shift
-dead_diaeresis 0x1a altgr
-dead_abovering 0x1a shift altgr
-plus 0x1b
-asterisk 0x1b shift
-asciitilde 0x1b altgr
-dead_tilde 0x1b altgr
-dead_macron 0x1b shift altgr
-ae 0x1e altgr
-AE 0x1e shift altgr
-eth 0x20 altgr
-ETH 0x20 shift altgr
-dstroke 0x21 altgr
-ordfeminine 0x21 shift altgr
-eng 0x22 altgr
-ENG 0x22 shift altgr
-hstroke 0x23 altgr
-Hstroke 0x23 shift altgr
-kra 0x25 altgr
-odiaeresis 0x27
-Odiaeresis 0x27 shift
-dead_doubleacute 0x27 altgr
-adiaeresis 0x28
-Adiaeresis 0x28 shift
-dead_caron 0x28 shift altgr
-asciicircum 0x29
-dead_circumflex 0x29
-degree 0x29 shift
-notsign 0x29 altgr
-numbersign 0x2b
-apostrophe 0x2b shift
-dead_breve 0x2b shift altgr
-y 0x2c addupper
-guillemotleft 0x2c altgr
-guillemotright 0x2d altgr
-cent 0x2e altgr
-copyright 0x2e shift altgr
-leftdoublequotemark 0x2f altgr
-rightdoublequotemark 0x30 altgr
-mu 0x32 altgr
-masculine 0x32 shift altgr
-comma 0x33
-semicolon 0x33 shift
-horizconnector 0x33 altgr
-multiply 0x33 shift altgr
-period 0x34
-colon 0x34 shift
-periodcentered 0x34 altgr
-division 0x34 shift altgr
-minus 0x35
-underscore 0x35 shift
-dead_belowdot 0x35 altgr
-dead_abovedot 0x35 shift altgr
+++ /dev/null
-# rdesktop Swiss-German (de-ch) keymap file
-# 2003-06-03 by noldi@tristar.ch
-#
-include common
-map 0x00000807
-#
-# Scan Code 1
-section 0x29
-degree 0x29 shift
-notsign 0x29 altgr inhibit
-#
-# Scan Code 2
-plus 0x2 shift
-brokenbar 0x02 altgr
-#
-# Scan Code 3
-quotedbl 0x03 shift
-at 0x03 altgr
-#
-# Scan Code 4
-asterisk 0x04 shift
-numbersign 0x04 altgr
-#
-# Scan Code 5
-ccedilla 0x05 shift
-onequarter 0x05 altgr inhibit
-#
-# Scan Code 6
-percent 0x06 shift
-onehalf 0x06 altgr inhibit
-#
-# Scan Code 7
-ampersand 0x07 shift
-notsign 0x07 altgr
-#
-# Scan Code 8
-slash 0x08 shift
-bar 0x08 altgr
-#
-# Scan Code 9
-parenleft 0x09 shift
-cent 0x09 altgr
-#
-# Scan Code 10
-parenright 0x0a shift
-#
-# Scan Code 11
-equal 0x0b shift
-braceright 0x0b altgr inhibit
-#
-# Scan Code 12
-apostrophe 0x0c
-question 0x0c shift
-dead_acute 0x0c altgr
-#
-# Scan Code 13
-dead_circumflex 0x0d
-dead_grave 0x0d shift
-dead_tilde 0x0d altgr
-#
-# Scan Code 19
-EuroSign 0x12 altgr
-#
-# Scan Code 22
-z 0x15 addupper
-#
-# Scan Code 27
-udiaeresis 0x1a
-egrave 0x1a shift
-bracketleft 0x1a altgr
-#
-# Scan Code 28
-dead_diaeresis 0x1b
-exclam 0x1b shift
-bracketright 0x1b altgr
-#
-# Scan Code 40
-odiaeresis 0x27
-eacute 0x27 shift
-#
-# Scan Code 41
-adiaeresis 0x28
-agrave 0x28 shift
-braceleft 0x28 altgr
-#
-# Scan Code 42 (only on international keyboards)
-dollar 0x2b
-sterling 0x2b shift
-braceright 0x2b altgr
-#
-# Scan Code 45 (only on international keyboards)
-backslash 0x56 altgr
-#
-# Scan Code 46
-y 0x2c addupper
-#
-# Scan Code 53
-comma 0x33
-semicolon 0x33 shift
-#
-# Scan Code 54
-period 0x34
-colon 0x34 shift
-#
-# Scan Code 55
-minus 0x35
-underscore 0x35 shift
-#
-# Suppress Windows unsupported AltGr keys
-#
-# Scan Code 17
-paragraph 0x10 altgr inhibit
-#
-# Scan Code 21
-tslash 0x14 altgr inhibit
-#
-# Scan Code 22
-leftarrow 0x15 altgr inhibit
-#
-# Scan Code 23
-downarrow 0x16 altgr inhibit
-#
-# Scan Code 24
-rightarrow 0x17 altgr inhibit
-#
-# Scan Code 25
-oslash 0x18 altgr inhibit
-#
-# Scan Code 26
-thorn 0x19 altgr inhibit
-#
-# Scan Code 31
-ae 0x1e altgr inhibit
-#
-# Scan Code 32
-ssharp 0x1f altgr inhibit
-#
-# Scan Code 33
-eth 0x20 altgr inhibit
-#
-# Scan Code 34
-dstroke 0x21 altgr inhibit
-#
-# Scan Code 35
-eng 0x22 altgr inhibit
-#
-# Scan Code 36
-hstroke 0x23 altgr inhibit
-#
-# Scan Code 38
-kra 0x25 altgr inhibit
-#
-# Scan Code 39
-lstroke 0x26 altgr inhibit
-#
-# Scan Code 46
-guillemotleft 0x2c altgr inhibit
-#
-# Scan Code 47
-guillemotright 0x2d altgr inhibit
-#
-# Scan Code 49
-leftdoublequotemark 0x2f altgr inhibit
-#
-# Scan Code 50
-rightdoublequotemark 0x30 altgr inhibit
-#
-# Scan Code 52
-mu 0x32 altgr inhibit
+++ /dev/null
-# generated from XKB map gb
-include common
-map 0x809
-exclam 0x02 shift
-onesuperior 0x02 altgr
-exclamdown 0x02 shift altgr
-quotedbl 0x03 shift
-twosuperior 0x03 altgr
-oneeighth 0x03 shift altgr
-sterling 0x04 shift
-threesuperior 0x04 altgr
-dollar 0x05 shift
-EuroSign 0x05 altgr
-percent 0x06 shift
-onehalf 0x06 altgr
-threeeighths 0x06 shift altgr
-asciicircum 0x07 shift
-threequarters 0x07 altgr
-fiveeighths 0x07 shift altgr
-ampersand 0x08 shift
-braceleft 0x08 altgr
-seveneighths 0x08 shift altgr
-asterisk 0x09 shift
-bracketleft 0x09 altgr
-trademark 0x09 shift altgr
-parenleft 0x0a shift
-bracketright 0x0a altgr
-plusminus 0x0a shift altgr
-parenright 0x0b shift
-braceright 0x0b altgr
-degree 0x0b shift altgr
-minus 0x0c
-underscore 0x0c shift
-backslash 0x0c altgr
-questiondown 0x0c shift altgr
-equal 0x0d
-plus 0x0d shift
-dead_cedilla 0x0d altgr
-dead_ogonek 0x0d shift altgr
-at 0x10 altgr
-Greek_OMEGA 0x10 shift altgr
-lstroke 0x11 altgr
-Lstroke 0x11 shift altgr
-paragraph 0x13 altgr
-registered 0x13 shift altgr
-tslash 0x14 altgr
-Tslash 0x14 shift altgr
-leftarrow 0x15 altgr
-yen 0x15 shift altgr
-downarrow 0x16 altgr
-uparrow 0x16 shift altgr
-rightarrow 0x17 altgr
-idotless 0x17 shift altgr
-oslash 0x18 altgr
-Ooblique 0x18 shift altgr
-thorn 0x19 altgr
-THORN 0x19 shift altgr
-bracketleft 0x1a
-braceleft 0x1a shift
-dead_diaeresis 0x1a altgr
-dead_abovering 0x1a shift altgr
-bracketright 0x1b
-braceright 0x1b shift
-dead_tilde 0x1b altgr
-dead_macron 0x1b shift altgr
-ae 0x1e altgr
-AE 0x1e shift altgr
-ssharp 0x1f altgr
-section 0x1f shift altgr
-eth 0x20 altgr
-ETH 0x20 shift altgr
-dstroke 0x21 altgr
-ordfeminine 0x21 shift altgr
-eng 0x22 altgr
-ENG 0x22 shift altgr
-hstroke 0x23 altgr
-Hstroke 0x23 shift altgr
-kra 0x25 altgr
-lstroke 0x26 altgr
-Lstroke 0x26 shift altgr
-semicolon 0x27
-colon 0x27 shift
-dead_acute 0x27 altgr
-dead_doubleacute 0x27 shift altgr
-apostrophe 0x28
-at 0x28 shift
-dead_circumflex 0x28 altgr
-dead_caron 0x28 shift altgr
-grave 0x29
-notsign 0x29 shift
-bar 0x29 altgr
-numbersign 0x2b
-asciitilde 0x2b shift
-dead_grave 0x2b altgr
-dead_breve 0x2b shift altgr
-guillemotleft 0x2c altgr
-less 0x2c shift altgr
-guillemotright 0x2d altgr
-greater 0x2d shift altgr
-cent 0x2e altgr
-copyright 0x2e shift altgr
-leftdoublequotemark 0x2f altgr
-rightdoublequotemark 0x30 altgr
-mu 0x32 altgr
-masculine 0x32 shift altgr
-comma 0x33
-less 0x33 shift
-horizconnector 0x33 altgr
-multiply 0x33 shift altgr
-period 0x34
-greater 0x34 shift
-periodcentered 0x34 altgr
-division 0x34 shift altgr
-slash 0x35
-question 0x35 shift
-dead_belowdot 0x35 altgr
-dead_abovedot 0x35 shift altgr
-backslash 0x56
-bar 0x56 shift
+++ /dev/null
-# generated from XKB map us
-include common
-map 0x409
-exclam 0x02 shift
-at 0x03 shift
-numbersign 0x04 shift
-dollar 0x05 shift
-percent 0x06 shift
-asciicircum 0x07 shift
-ampersand 0x08 shift
-asterisk 0x09 shift
-parenleft 0x0a shift
-parenright 0x0b shift
-minus 0x0c
-underscore 0x0c shift
-equal 0x0d
-plus 0x0d shift
-bracketleft 0x1a
-braceleft 0x1a shift
-bracketright 0x1b
-braceright 0x1b shift
-semicolon 0x27
-colon 0x27 shift
-apostrophe 0x28
-quotedbl 0x28 shift
-grave 0x29
-asciitilde 0x29 shift
-backslash 0x2b
-bar 0x2b shift
-comma 0x33
-less 0x33 shift
-period 0x34
-greater 0x34 shift
-slash 0x35
-question 0x35 shift
+++ /dev/null
-# generated from XKB map es
-include common
-map 0x40a
-exclam 0x02 shift
-bar 0x02 altgr
-quotedbl 0x03 shift
-at 0x03 altgr
-oneeighth 0x03 shift altgr
-periodcentered 0x04 shift
-numbersign 0x04 altgr
-sterling 0x04 shift altgr
-dollar 0x05 shift
-asciitilde 0x05 altgr
-percent 0x06 shift
-onehalf 0x06 altgr
-threeeighths 0x06 shift altgr
-ampersand 0x07 shift
-notsign 0x07 altgr
-fiveeighths 0x07 shift altgr
-slash 0x08 shift
-seveneighths 0x08 shift altgr
-parenleft 0x09 shift
-trademark 0x09 shift altgr
-parenright 0x0a shift
-plusminus 0x0a shift altgr
-equal 0x0b shift
-degree 0x0b shift altgr
-apostrophe 0x0c
-question 0x0c shift
-exclamdown 0x0d
-questiondown 0x0d shift
-Greek_OMEGA 0x10 shift altgr
-lstroke 0x11 altgr
-Lstroke 0x11 shift altgr
-EuroSign 0x12 altgr
-paragraph 0x13 altgr
-registered 0x13 shift altgr
-tslash 0x14 altgr
-Tslash 0x14 shift altgr
-leftarrow 0x15 altgr
-yen 0x15 shift altgr
-downarrow 0x16 altgr
-uparrow 0x16 shift altgr
-rightarrow 0x17 altgr
-idotless 0x17 shift altgr
-oslash 0x18 altgr
-Ooblique 0x18 shift altgr
-thorn 0x19 altgr
-THORN 0x19 shift altgr
-dead_grave 0x1a
-dead_circumflex 0x1a shift
-bracketleft 0x1a altgr
-dead_abovering 0x1a shift altgr
-plus 0x1b
-asterisk 0x1b shift
-bracketright 0x1b altgr
-dead_macron 0x1b shift altgr
-ae 0x1e altgr
-AE 0x1e shift altgr
-ssharp 0x1f altgr
-section 0x1f shift altgr
-eth 0x20 altgr
-ETH 0x20 shift altgr
-dstroke 0x21 altgr
-eng 0x22 altgr
-ENG 0x22 shift altgr
-hstroke 0x23 altgr
-Hstroke 0x23 shift altgr
-kra 0x25 altgr
-lstroke 0x26 altgr
-Lstroke 0x26 shift altgr
-ntilde 0x27
-Ntilde 0x27 shift
-dead_doubleacute 0x27 shift altgr
-dead_acute 0x28
-dead_diaeresis 0x28 shift
-braceleft 0x28 altgr
-masculine 0x29
-ordfeminine 0x29 shift
-backslash 0x29 altgr
-ccedilla 0x2b
-Ccedilla 0x2b shift
-braceright 0x2b altgr
-dead_breve 0x2b shift altgr
-guillemotleft 0x2c altgr
-less 0x56
-greater 0x56 shift
-guillemotright 0x2d altgr
-cent 0x2e altgr
-copyright 0x2e shift altgr
-leftdoublequotemark 0x2f altgr
-grave 0x2f shift altgr
-rightdoublequotemark 0x30 altgr
-mu 0x32 altgr
-comma 0x33
-semicolon 0x33 shift
-horizconnector 0x33 altgr
-multiply 0x33 shift altgr
-period 0x34
-colon 0x34 shift
-division 0x34 shift altgr
-minus 0x35
-underscore 0x35 shift
-dead_belowdot 0x35 altgr
-dead_abovedot 0x35 shift altgr
+++ /dev/null
-map 0x00000425
-include common
-
-#
-# Top row
-#
-dead_caron 0x29
-dead_tilde 0x29 shift
-
-# 1
-exclam 0x2 shift
-
-# 2
-quotedbl 0x3 shift
-at 0x3 altgr
-
-# 3
-numbersign 0x4 shift
-sterling 0x4 altgr
-# 4
-currency 0x5 shift
-dollar 0x5 altgr
-# 5
-percent 0x6 shift
-# 6
-ampersand 0x7 shift
-# 7
-slash 0x8 shift
-braceleft 0x8 altgr
-# 8
-parenleft 0x9 shift
-bracketleft 0x9 altgr
-# 9
-parenright 0xa shift
-bracketright 0xa altgr
-# 0
-equal 0xb shift
-braceright 0xb altgr
-
-plus 0xc
-question 0xc shift
-backslash 0xc altgr
-
-acute 0xd
-dead_acute 0xd
-grave 0xd shift
-dead_grave 0xd shift
-
-#
-# QWERTY first row
-#
-EuroSign 0x12 altgr
-udiaeresis 0x1a
-Udiaeresis 0x1a shift
-otilde 0x1b
-Otilde 0x1b shift
-section 0x1b altgr
-
-#
-# QWERTY second row
-#
-scaron 0x1f altgr
-Scaron 0x1f altgr shift
-odiaeresis 0x27
-Odiaeresis 0x27 shift
-adiaeresis 0x28
-Adiaeresis 0x28 shift
-asciicircum 0x28 altgr
-apostrophe 0x2b
-asterisk 0x2b shift
-onehalf 0x2b altgr
-#
-# QWERTY third row
-#
-less 0x56
-greater 0x56 shift
-bar 0x56 altgr
-zcaron 0x2c altgr
-Zcaron 0x2c altgr shift
-comma 0x33
-semicolon 0x33 shift
-period 0x34
-colon 0x34 shift
-minus 0x35
-underscore 0x35 shift
-
+++ /dev/null
-# generated from XKB map se_FI
-include common
-map 0x40b
-exclam 0x02 shift
-exclamdown 0x02 altgr
-onesuperior 0x02 shift altgr
-quotedbl 0x03 shift
-at 0x03 altgr
-twosuperior 0x03 shift altgr
-numbersign 0x04 shift
-sterling 0x04 altgr
-threesuperior 0x04 shift altgr
-currency 0x05 shift
-dollar 0x05 altgr
-onequarter 0x05 shift altgr
-percent 0x06 shift
-onehalf 0x06 altgr
-cent 0x06 shift altgr
-ampersand 0x07 shift
-yen 0x07 altgr
-fiveeighths 0x07 shift altgr
-slash 0x08 shift
-braceleft 0x08 altgr
-division 0x08 shift altgr
-parenleft 0x09 shift
-bracketleft 0x09 altgr
-guillemotleft 0x09 shift altgr
-parenright 0x0a shift
-bracketright 0x0a altgr
-guillemotright 0x0a shift altgr
-equal 0x0b shift
-braceright 0x0b altgr
-degree 0x0b shift altgr
-plus 0x0c
-question 0x0c shift
-backslash 0x0c altgr
-questiondown 0x0c shift altgr
-dead_acute 0x0d
-dead_grave 0x0d shift
-plusminus 0x0d altgr
-notsign 0x0d shift altgr
-at 0x10 altgr
-Greek_OMEGA 0x10 shift altgr
-lstroke 0x11 altgr
-Lstroke 0x11 shift altgr
-EuroSign 0x12 altgr
-cent 0x12 shift altgr
-registered 0x13 altgr
-thorn 0x14 altgr
-THORN 0x14 shift altgr
-leftarrow 0x15 altgr
-yen 0x15 shift altgr
-downarrow 0x16 altgr
-uparrow 0x16 shift altgr
-rightarrow 0x17 altgr
-idotless 0x17 shift altgr
-oe 0x18 altgr
-OE 0x18 shift altgr
-thorn 0x19 altgr
-THORN 0x19 shift altgr
-aring 0x1a
-Aring 0x1a shift
-dead_diaeresis 0x1a altgr
-dead_abovering 0x1a shift altgr
-dead_diaeresis 0x1b
-dead_circumflex 0x1b shift
-dead_tilde 0x1b altgr
-dead_caron 0x1b shift altgr
-ordfeminine 0x1e altgr
-masculine 0x1e shift altgr
-ssharp 0x1f altgr
-section 0x1f shift altgr
-eth 0x20 altgr
-ETH 0x20 shift altgr
-dstroke 0x21 altgr
-ordfeminine 0x21 shift altgr
-eng 0x22 altgr
-ENG 0x22 shift altgr
-hstroke 0x23 altgr
-Hstroke 0x23 shift altgr
-kra 0x25 altgr
-ampersand 0x25 shift altgr
-lstroke 0x26 altgr
-Lstroke 0x26 shift altgr
-odiaeresis 0x27
-Odiaeresis 0x27 shift
-oslash 0x27 altgr
-Ooblique 0x27 shift altgr
-adiaeresis 0x28
-Adiaeresis 0x28 shift
-ae 0x28 altgr
-AE 0x28 shift altgr
-section 0x29
-onehalf 0x29 shift
-paragraph 0x29 altgr
-threequarters 0x29 shift altgr
-apostrophe 0x2b
-asterisk 0x2b shift
-acute 0x2b altgr
-multiply 0x2b shift altgr
-guillemotleft 0x2c altgr
-less 0x2c shift altgr
-guillemotright 0x2d altgr
-greater 0x2d shift altgr
-copyright 0x2e altgr
-leftdoublequotemark 0x2f altgr
-grave 0x2f shift altgr
-rightdoublequotemark 0x30 altgr
-apostrophe 0x30 shift altgr
-mu 0x32 altgr
-masculine 0x32 shift altgr
-comma 0x33
-semicolon 0x33 shift
-dead_cedilla 0x33 altgr
-dead_ogonek 0x33 shift altgr
-period 0x34
-colon 0x34 shift
-periodcentered 0x34 altgr
-dead_abovedot 0x34 shift altgr
-minus 0x35
-underscore 0x35 shift
-hyphen 0x35 altgr
-macron 0x35 shift altgr
-nobreakspace 0x39 altgr
+++ /dev/null
-map 0x438
-include common
-
-#
-# Top row
-#
-onehalf 0x29
-section 0x29 shift
-
-# 1
-exclam 0x2 shift
-
-# 2
-quotedbl 0x3 shift
-at 0x3 altgr
-
-# 3
-numbersign 0x4 shift
-sterling 0x4 altgr
-# 4
-currency 0x5 shift
-dollar 0x5 altgr
-# 5
-percent 0x6 shift
-# 6
-ampersand 0x7 shift
-# 7
-slash 0x8 shift
-braceleft 0x8 altgr
-# 8
-parenleft 0x9 shift
-bracketleft 0x9 altgr
-# 9
-parenright 0xa shift
-bracketright 0xa altgr
-# 0
-equal 0xb shift
-braceright 0xb altgr
-
-plus 0xc
-question 0xc shift
-plusminus 0xc altgr
-
-bar 0xd altgr
-dead_acute 0xd
-
-#
-# QWERTY first row
-#
-EuroSign 0x12 altgr
-aring 0x1a
-Aring 0x1a shift
-eth 0x1b addupper
-asciitilde 0x1b altgr
-
-#
-# QWERTY second row
-#
-ae 0x27 addupper
-oslash 0x28
-Ooblique 0x28 shift
-apostrophe 0x2b
-asterisk 0x2b shift
-
-#
-# QWERTY third row
-#
-less 0x56
-greater 0x56 shift
-backslash 0x56 altgr
-comma 0x33
-semicolon 0x33 shift
-period 0x34
-colon 0x34 shift
-minus 0x35
-underscore 0x35 shift
-
+++ /dev/null
-include common
-map 0x40c
-#
-# Top row
-#
-twosuperior 0x29
-notsign 0x29 altgr
-
-ampersand 0x02
-1 0x02 shift
-onesuperior 0x02 altgr
-exclamdown 0x02 shift altgr
-
-eacute 0x03
-2 0x03 shift
-asciitilde 0x03 altgr
-oneeighth 0x03 shift altgr
-
-quotedbl 0x04
-3 0x04 shift
-numbersign 0x04 altgr
-
-apostrophe 0x05
-4 0x05 shift
-braceleft 0x05 altgr
-
-parenleft 0x06
-5 0x06 shift
-bracketleft 0x06 altgr
-threeeighths 0x06 shift altgr
-
-minus 0x07
-6 0x07 shift
-bar 0x07 altgr
-fiveeighths 0x07 shift altgr
-
-egrave 0x08
-7 0x08 shift
-grave 0x08 altgr
-seveneighths 0x08 shift altgr
-
-underscore 0x09
-8 0x09 shift
-backslash 0x09 altgr
-trademark 0x09 shift altgr
-
-ccedilla 0x0a
-9 0x0a shift
-asciicircum 0x0a altgr
-plusminus 0x0a shift altgr
-
-agrave 0x0b
-0 0x0b shift
-at 0x0b altgr
-
-parenright 0x0c
-degree 0x0c shift
-bracketright 0x0c altgr
-questiondown 0x0c shift altgr
-
-equal 0x0d
-plus 0x0d shift
-braceright 0x0d altgr
-dead_ogonek 0x0d shift altgr
-
-#
-# AZERTY first row
-#
-
-a 0x10 addupper
-ae 0x10 altgr
-AE 0x10 shift altgr
-
-z 0x11 addupper
-guillemotleft 0x11 altgr
-
-EuroSign 0x12 altgr
-
-paragraph 0x13 altgr
-registered 0x13 shift altgr
-
-tslash 0x14 altgr
-Tslash 0x14 shift altgr
-
-leftarrow 0x15 altgr
-yen 0x15 shift altgr
-
-downarrow 0x16 altgr
-uparrow 0x16 shift altgr
-
-rightarrow 0x17 altgr
-idotless 0x17 shift altgr
-
-oslash 0x18 altgr
-Ooblique 0x18 shift altgr
-
-thorn 0x19 altgr
-THORN 0x19 shift altgr
-
-dead_circumflex 0x1a
-dead_diaeresis 0x1a shift
-dead_abovering 0x1a shift altgr
-
-dollar 0x1b
-sterling 0x1b shift
-currency 0x1b altgr
-dead_macron 0x1b shift altgr
-
-#
-# AZERTY second row
-#
-q 0x1e addupper
-Greek_OMEGA 0x1e shift altgr
-
-ssharp 0x1f altgr
-
-eth 0x20 altgr
-ETH 0x20 shift altgr
-
-dstroke 0x21 altgr
-ordfeminine 0x21 shift altgr
-
-eng 0x22 altgr
-ENG 0x22 shift altgr
-
-hstroke 0x23 altgr
-Hstroke 0x23 shift altgr
-
-kra 0x25 altgr
-
-lstroke 0x26 altgr
-Lstroke 0x26 shift altgr
-
-m 0x27 addupper
-masculine 0x27 shift altgr
-
-ugrave 0x28
-percent 0x28 shift
-dead_caron 0x28 shift altgr
-
-asterisk 0x2b
-mu 0x2b shift
-dead_grave 0x2b altgr
-dead_breve 0x2b shift altgr
-
-#
-# AZERTY third row
-#
-less 0x56
-greater 0x56 shift
-
-w 0x2c addupper
-
-guillemotright 0x2d altgr
-
-cent 0x2e altgr
-copyright 0x2e shift altgr
-
-leftdoublequotemark 0x2f altgr
-
-rightdoublequotemark 0x30 altgr
-
-comma 0x32
-question 0x32 shift
-dead_acute 0x32 altgr
-dead_doubleacute 0x32 shift altgr
-
-semicolon 0x33
-period 0x33 shift
-horizconnector 0x33 altgr
-multiply 0x33 shift altgr
-
-colon 0x34
-slash 0x34 shift
-periodcentered 0x34 altgr
-division 0x34 shift altgr
-
-exclam 0x35
-section 0x35 shift
-dead_belowdot 0x35 altgr
-dead_abovedot 0x35 shift altgr
+++ /dev/null
-# generated from XKB map be
-include common
-map 0x80c
-ampersand 0x02
-1 0x02 shift
-bar 0x02 altgr
-exclamdown 0x02 shift altgr
-eacute 0x03
-2 0x03 shift
-at 0x03 altgr
-oneeighth 0x03 shift altgr
-quotedbl 0x04
-3 0x04 shift
-numbersign 0x04 altgr
-sterling 0x04 shift altgr
-apostrophe 0x05
-4 0x05 shift
-onequarter 0x05 altgr
-dollar 0x05 shift altgr
-parenleft 0x06
-5 0x06 shift
-onehalf 0x06 altgr
-threeeighths 0x06 shift altgr
-section 0x07
-6 0x07 shift
-asciicircum 0x07 altgr
-fiveeighths 0x07 shift altgr
-egrave 0x08
-7 0x08 shift
-braceleft 0x08 altgr
-seveneighths 0x08 shift altgr
-exclam 0x09
-8 0x09 shift
-bracketleft 0x09 altgr
-trademark 0x09 shift altgr
-ccedilla 0x0a
-9 0x0a shift
-braceleft 0x0a altgr
-plusminus 0x0a shift altgr
-agrave 0x0b
-0 0x0b shift
-braceright 0x0b altgr
-degree 0x0b shift altgr
-parenright 0x0c
-degree 0x0c shift
-backslash 0x0c altgr
-questiondown 0x0c shift altgr
-minus 0x0d
-underscore 0x0d shift
-dead_cedilla 0x0d altgr
-dead_ogonek 0x0d shift altgr
-a 0x10 addupper
-at 0x10 altgr
-Greek_OMEGA 0x10 shift altgr
-z 0x11 addupper
-lstroke 0x11 altgr
-Lstroke 0x11 shift altgr
-EuroSign 0x12 altgr
-cent 0x12 shift altgr
-paragraph 0x13 altgr
-registered 0x13 shift altgr
-tslash 0x14 altgr
-Tslash 0x14 shift altgr
-leftarrow 0x15 altgr
-yen 0x15 shift altgr
-downarrow 0x16 altgr
-uparrow 0x16 shift altgr
-rightarrow 0x17 altgr
-idotless 0x17 shift altgr
-oslash 0x18 altgr
-Ooblique 0x18 shift altgr
-thorn 0x19 altgr
-THORN 0x19 shift altgr
-dead_circumflex 0x1a
-dead_diaeresis 0x1a shift
-bracketleft 0x1a altgr
-dead_abovering 0x1a shift altgr
-dollar 0x1b
-asterisk 0x1b shift
-bracketright 0x1b altgr
-dead_macron 0x1b shift altgr
-q 0x1e addupper
-ae 0x1e altgr
-AE 0x1e shift altgr
-ssharp 0x1f altgr
-section 0x1f shift altgr
-eth 0x20 altgr
-ETH 0x20 shift altgr
-dstroke 0x21 altgr
-ordfeminine 0x21 shift altgr
-eng 0x22 altgr
-ENG 0x22 shift altgr
-hstroke 0x23 altgr
-Hstroke 0x23 shift altgr
-kra 0x25 altgr
-ampersand 0x25 shift altgr
-lstroke 0x26 altgr
-Lstroke 0x26 shift altgr
-m 0x27 addupper
-dead_acute 0x27 altgr
-dead_doubleacute 0x27 shift altgr
-ugrave 0x28
-percent 0x28 shift
-dead_acute 0x28 altgr
-dead_caron 0x28 shift altgr
-twosuperior 0x29
-threesuperior 0x29 shift
-notsign 0x29 altgr
-mu 0x2b
-sterling 0x2b shift
-dead_grave 0x2b altgr
-dead_breve 0x2b shift altgr
-w 0x2c addupper
-guillemotleft 0x2c altgr
-less 0x2c shift altgr
-guillemotright 0x2d altgr
-greater 0x2d shift altgr
-cent 0x2e altgr
-copyright 0x2e shift altgr
-leftdoublequotemark 0x2f altgr
-grave 0x2f shift altgr
-rightdoublequotemark 0x30 altgr
-apostrophe 0x30 shift altgr
-comma 0x32
-question 0x32 shift
-dead_cedilla 0x32 altgr
-masculine 0x32 shift altgr
-semicolon 0x33
-period 0x33 shift
-horizconnector 0x33 altgr
-multiply 0x33 shift altgr
-colon 0x34
-slash 0x34 shift
-periodcentered 0x34 altgr
-division 0x34 shift altgr
-equal 0x35
-plus 0x35 shift
-dead_tilde 0x35 altgr
-dead_abovedot 0x35 shift altgr
-backslash 0x56 altgr
+++ /dev/null
-# Canadian French
-# By Simon Germain
-include common
-map 0xc0c
-
-backslash 0x29 altgr
-plusminus 0x2 altgr
-at 0x3 altgr
-sterling 0x4 altgr
-cent 0x5 altgr
-currency 0x6 altgr
-notsign 0x7 altgr
-bar 0x29 shift
-twosuperior 0x9 altgr
-threesuperior 0xa altgr
-onequarter 0xb altgr
-onehalf 0xc altgr
-threequarters 0xd altgr
-section 0x18 altgr
-paragraph 0x19 altgr
-bracketleft 0x1a altgr
-bracketright 0x1b altgr
-asciitilde 0x27 altgr
-braceleft 0x28 altgr
-braceright 0x2b altgr
-less 0x2b
-greater 0x2b shift
-guillemotleft 0x56
-guillemotright 0x56 shift
-degree 0x56 altgr
-mu 0x32 altgr
-eacute 0x35
-dead_acute 0x35 altgr
-dead_grave 0x28
-dead_circumflex 0x1a
-dead_circumflex 0x1a shift
-dead_cedilla 0x1b
-dead_diaeresis 0x1b shift
-exclam 0x2 shift
-quotedbl 0x3 shift
-slash 0x4 shift
-dollar 0x5 shift
-percent 0x6 shift
-question 0x7 shift
-ampersand 0x8 shift
-asterisk 0x9 shift
-parenleft 0xa shift
-parenright 0xb shift
-underscore 0xc shift
-plus 0xd shift
+++ /dev/null
-# generated from XKB map fr_CH
-include common
-map 0x100c
-exclam 0x02 shift
-onesuperior 0x02 altgr
-exclamdown 0x02 shift altgr
-quotedbl 0x03 shift
-twosuperior 0x03 altgr
-oneeighth 0x03 shift altgr
-section 0x04 shift
-threesuperior 0x04 altgr
-sterling 0x04 shift altgr
-dollar 0x05 shift
-onequarter 0x05 altgr
-currency 0x05 shift altgr
-percent 0x06 shift
-onehalf 0x06 altgr
-threeeighths 0x06 shift altgr
-ampersand 0x07 shift
-threequarters 0x07 altgr
-fiveeighths 0x07 shift altgr
-slash 0x08 shift
-braceleft 0x08 altgr
-seveneighths 0x08 shift altgr
-parenleft 0x09 shift
-bracketleft 0x09 altgr
-trademark 0x09 shift altgr
-parenright 0x0a shift
-bracketright 0x0a altgr
-plusminus 0x0a shift altgr
-equal 0x0b shift
-braceright 0x0b altgr
-ssharp 0x0c
-question 0x0c shift
-backslash 0x0c altgr
-questiondown 0x0c shift altgr
-acute 0x0d
-dead_acute 0x0d
-grave 0x0d shift
-dead_grave 0x0d shift
-dead_cedilla 0x0d altgr
-dead_ogonek 0x0d shift altgr
-at 0x10 altgr
-Greek_OMEGA 0x10 shift altgr
-EuroSign 0x12 altgr
-paragraph 0x13 altgr
-registered 0x13 shift altgr
-tslash 0x14 altgr
-Tslash 0x14 shift altgr
-z 0x15 addupper
-leftarrow 0x15 altgr
-yen 0x15 shift altgr
-downarrow 0x16 altgr
-uparrow 0x16 shift altgr
-rightarrow 0x17 altgr
-idotless 0x17 shift altgr
-oslash 0x18 altgr
-Ooblique 0x18 shift altgr
-thorn 0x19 altgr
-THORN 0x19 shift altgr
-udiaeresis 0x1a
-Udiaeresis 0x1a shift
-dead_diaeresis 0x1a altgr
-dead_abovering 0x1a shift altgr
-plus 0x1b
-asterisk 0x1b shift
-asciitilde 0x1b altgr
-dead_tilde 0x1b altgr
-dead_macron 0x1b shift altgr
-ae 0x1e altgr
-AE 0x1e shift altgr
-eth 0x20 altgr
-ETH 0x20 shift altgr
-dstroke 0x21 altgr
-ordfeminine 0x21 shift altgr
-eng 0x22 altgr
-ENG 0x22 shift altgr
-hstroke 0x23 altgr
-Hstroke 0x23 shift altgr
-kra 0x25 altgr
-odiaeresis 0x27
-Odiaeresis 0x27 shift
-dead_doubleacute 0x27 altgr
-adiaeresis 0x28
-Adiaeresis 0x28 shift
-dead_caron 0x28 shift altgr
-asciicircum 0x29
-dead_circumflex 0x29
-degree 0x29 shift
-notsign 0x29 altgr
-numbersign 0x2b
-apostrophe 0x2b shift
-dead_breve 0x2b shift altgr
-y 0x2c addupper
-guillemotleft 0x2c altgr
-guillemotright 0x2d altgr
-cent 0x2e altgr
-copyright 0x2e shift altgr
-leftdoublequotemark 0x2f altgr
-rightdoublequotemark 0x30 altgr
-mu 0x32 altgr
-masculine 0x32 shift altgr
-comma 0x33
-semicolon 0x33 shift
-horizconnector 0x33 altgr
-multiply 0x33 shift altgr
-period 0x34
-colon 0x34 shift
-periodcentered 0x34 altgr
-division 0x34 shift altgr
-minus 0x35
-underscore 0x35 shift
-dead_belowdot 0x35 altgr
-dead_abovedot 0x35 shift altgr
+++ /dev/null
-# generated from XKB map hr
-include common
-map 0x41a
-exclam 0x02 shift
-asciitilde 0x02 altgr
-dead_tilde 0x02 shift altgr
-quotedbl 0x03 shift
-dead_caron 0x03 altgr
-caron 0x03 shift altgr
-numbersign 0x04 shift
-asciicircum 0x04 altgr
-dead_circumflex 0x04 shift altgr
-dollar 0x05 shift
-dead_breve 0x05 altgr
-breve 0x05 shift altgr
-percent 0x06 shift
-degree 0x06 altgr
-dead_abovering 0x06 shift altgr
-ampersand 0x07 shift
-dead_ogonek 0x07 altgr
-ogonek 0x07 shift altgr
-slash 0x08 shift
-grave 0x08 altgr
-dead_grave 0x08 shift altgr
-parenleft 0x09 shift
-dead_abovedot 0x09 altgr
-abovedot 0x09 shift altgr
-parenright 0x0a shift
-dead_acute 0x0a altgr
-apostrophe 0x0a shift altgr
-equal 0x0b shift
-dead_doubleacute 0x0b altgr
-doubleacute 0x0b shift altgr
-apostrophe 0x0c
-question 0x0c shift
-dead_diaeresis 0x0c altgr
-diaeresis 0x0c shift altgr
-plus 0x0d
-asterisk 0x0d shift
-dead_cedilla 0x0d altgr
-cedilla 0x0d shift altgr
-backslash 0x10 altgr
-Greek_OMEGA 0x10 shift altgr
-bar 0x11 altgr
-Lstroke 0x11 shift altgr
-EuroSign 0x12 altgr
-paragraph 0x13 altgr
-registered 0x13 shift altgr
-tslash 0x14 altgr
-Tslash 0x14 shift altgr
-z 0x15 addupper
-leftarrow 0x15 altgr
-yen 0x15 shift altgr
-downarrow 0x16 altgr
-uparrow 0x16 shift altgr
-rightarrow 0x17 altgr
-idotless 0x17 shift altgr
-oslash 0x18 altgr
-Ooblique 0x18 shift altgr
-thorn 0x19 altgr
-THORN 0x19 shift altgr
-scaron 0x1a
-Scaron 0x1a shift
-division 0x1a altgr
-dead_abovering 0x1a shift altgr
-dstroke 0x1b
-Dstroke 0x1b shift
-multiply 0x1b altgr
-dead_macron 0x1b shift altgr
-ae 0x1e altgr
-AE 0x1e shift altgr
-ssharp 0x1f altgr
-section 0x1f shift altgr
-eth 0x20 altgr
-ETH 0x20 shift altgr
-bracketleft 0x21 altgr
-ordfeminine 0x21 shift altgr
-bracketright 0x22 altgr
-ENG 0x22 shift altgr
-hstroke 0x23 altgr
-Hstroke 0x23 shift altgr
-lstroke 0x25 altgr
-ampersand 0x25 shift altgr
-Lstroke 0x26 altgr
-ccaron 0x27
-Ccaron 0x27 shift
-dead_acute 0x27 altgr
-dead_doubleacute 0x27 shift altgr
-cacute 0x28
-Cacute 0x28 shift
-ssharp 0x28 altgr
-dead_caron 0x28 shift altgr
-dead_cedilla 0x29
-dead_diaeresis 0x29 shift
-notsign 0x29 altgr
-zcaron 0x2b
-Zcaron 0x2b shift
-currency 0x2b altgr
-dead_breve 0x2b shift altgr
-y 0x2c addupper
-guillemotleft 0x2c altgr
-less 0x2c shift altgr
-guillemotright 0x2d altgr
-greater 0x2d shift altgr
-cent 0x2e altgr
-copyright 0x2e shift altgr
-at 0x2f altgr
-grave 0x2f shift altgr
-braceleft 0x30 altgr
-apostrophe 0x30 shift altgr
-braceright 0x31 altgr
-section 0x32 altgr
-masculine 0x32 shift altgr
-comma 0x33
-semicolon 0x33 shift
-horizconnector 0x33 altgr
-multiply 0x33 shift altgr
-period 0x34
-colon 0x34 shift
-periodcentered 0x34 altgr
-division 0x34 shift altgr
-minus 0x35
-underscore 0x35 shift
-dead_belowdot 0x35 altgr
-dead_abovedot 0x35 shift altgr
+++ /dev/null
-# Hungarian keyboard layout (QWERTZ)
-# Created by: The NeverGone <never@delfin.klte.hu>
-
-include common
-map 0x40e
-
-
-# AltGr keys:
-notsign 0x29 altgr
-asciitilde 0x02 altgr
-caron 0x03 altgr
-asciicircum 0x04 altgr
-breve 0x05 altgr
-degree 0x06 altgr
-ogonek 0x07 altgr
-grave 0x08 altgr
-abovedot 0x09 altgr
-acute 0x0a altgr
-doubleacute 0x0b altgr
-diaeresis 0x0c altgr
-cedilla 0x0d altgr
-backslash 0x10 altgr
-bar 0x11 altgr
-EuroSign 0x12 altgr
-Iacute 0x17 altgr
-division 0x1a altgr
-multiply 0x1b altgr
-dstroke 0x1f altgr
-Dstroke 0x20 altgr
-bracketleft 0x21 altgr
-bracketright 0x22 altgr
-iacute 0x24 altgr
-lstroke 0x25 altgr
-Lstroke 0x26 altgr
-dollar 0x27 altgr
-ssharp 0x28 altgr
-currency 0x2b altgr
-less 0x56 altgr
-greater 0x2c altgr
-numbersign 0x2d altgr
-ampersand 0x2e altgr
-at 0x2f altgr
-braceleft 0x30 altgr
-braceright 0x31 altgr
-semicolon 0x33 altgr
-asterisk 0x35 altgr
-
-
-# Shift keys:
-section 0x29 shift
-apostrophe 0x02 shift
-quotedbl 0x03 shift
-plus 0x04 shift
-exclam 0x05 shift
-percent 0x06 shift
-slash 0x07 shift
-equal 0x08 shift
-parenleft 0x09 shift
-parenright 0x0a shift
-Odiaeresis 0x0b shift
-Udiaeresis 0x0c shift
-Oacute 0x0d shift
-Z 0x15 shift
-Odoubleacute 0x1a shift
-Uacute 0x1b shift
-Eacute 0x27 shift
-Aacute 0x28 shift
-Udoubleacute 0x2b shift
-Y 0x2c shift
-question 0x33 shift
-colon 0x34 shift
-underscore 0x35 shift
-F13 0x3b shift
-F14 0x3c shift
-F15 0x3d shift
-F16 0x3e shift
-F17 0x3f shift
-F18 0x40 shift
-F19 0x41 shift
-F20 0x42 shift
-F21 0x43 shift
-F22 0x44 shift
-F23 0x57 shift
-F24 0x58 shift
-
-
-# Ctrl keys:
-F25 0x3b ctrl
-F26 0x3c ctrl
-F27 0x3d ctrl
-F28 0x3e ctrl
-F29 0x3f ctrl
-F30 0x40 ctrl
-F31 0x41 ctrl
-F32 0x42 ctrl
-F33 0x43 ctrl
-F34 0x44 ctrl
-F35 0x57 ctrl
-#NoSymbol 0x58 ctrl
-
-
-0 0x29
-odiaeresis 0x0b
-udiaeresis 0x0c
-oacute 0x0d
-z 0x15
-odoubleacute 0x1a
-uacute 0x1b
-eacute 0x27
-aacute 0x28
-udoubleacute 0x2b
-y 0x2c
-comma 0x33
-period 0x34
-minus 0x35
+++ /dev/null
-# 2004-03-16 Halldór Guðmundsson and Morten Lange
-# Keyboard definition file for the Icelandic keyboard
-# to be used in rdesktop 1.3.x ( See rdesktop.org)
-# generated from XKB map de, and changed manually
-# Location for example /usr/local/share/rdesktop/keymaps/is
-include common
-map 0x40f
-exclam 0x02 shift
-onesuperior 0x02 altgr
-exclamdown 0x02 shift altgr
-quotedbl 0x03 shift
-twosuperior 0x03 altgr
-oneeighth 0x03 shift altgr
-#section 0x04 shift
-numbersign 0x04 shift
-threesuperior 0x04 altgr
-sterling 0x04 shift altgr
-dollar 0x05 shift
-onequarter 0x05 altgr
-currency 0x05 shift altgr
-percent 0x06 shift
-onehalf 0x06 altgr
-threeeighths 0x06 shift altgr
-ampersand 0x07 shift
-threequarters 0x07 altgr
-fiveeighths 0x07 shift altgr
-slash 0x08 shift
-braceleft 0x08 altgr
-seveneighths 0x08 shift altgr
-parenleft 0x09 shift
-bracketleft 0x09 altgr
-trademark 0x09 shift altgr
-parenright 0x0a shift
-bracketright 0x0a altgr
-plusminus 0x0a shift altgr
-equal 0x0b shift
-braceright 0x0b altgr
-#ssharp 0x0c
-odiaeresis 0x0c
-#question 0x0c shift
-Odiaeresis 0x0c shift
-backslash 0x0c altgr
-questiondown 0x0c shift altgr
-#acute 0x0d
-minus 0x0d
-#dead_acute 0x0d
-#grave 0x0d shift
-#dead_grave 0x0d shift
-underscore 0x0d shift
-dead_cedilla 0x0d altgr
-dead_ogonek 0x0d shift altgr
-at 0x10 altgr
-Greek_OMEGA 0x10 shift altgr
-EuroSign 0x12 altgr
-paragraph 0x13 altgr
-registered 0x13 shift altgr
-tslash 0x14 altgr
-Tslash 0x14 shift altgr
-#z 0x15 addupper
-leftarrow 0x15 altgr
-yen 0x15 shift altgr
-downarrow 0x16 altgr
-uparrow 0x16 shift altgr
-rightarrow 0x17 altgr
-idotless 0x17 shift altgr
-oslash 0x18 altgr
-Ooblique 0x18 shift altgr
-#thorn 0x19 altgr
-#THORN 0x19 shift altgr
-#udiaeresis 0x1a
-#Udiaeresis 0x1a shift
-#dead_diaeresis 0x1a altgr
-#dead_abovering 0x1a shift altgr
-eth 0x1a
-ETH 0x1a shift
-apostrophe 0x1b
-question 0x1b shift
-#plus 0x1b
-#asterisk 0x1b shift
-asciitilde 0x1b altgr
-#grave 0x1b altgr
-#dead_tilde 0x1b altgr
-#dead_macron 0x1b shift altgr
-#ae 0x1e altgr
-#AE 0x1e shift altgr
-#eth 0x20 altgr
-#eth 0x20
-#ETH 0x20 shift altgr
-#ETH 0x20 shift
-dstroke 0x21 altgr
-ordfeminine 0x21 shift altgr
-eng 0x22 altgr
-ENG 0x22 shift altgr
-hstroke 0x23 altgr
-Hstroke 0x23 shift altgr
-kra 0x25 altgr
-#adiaeresis 0x27
-#Adiaeresis 0x27 shift
-ae 0x27
-AE 0x27 shift
-dead_doubleacute 0x27 altgr
-#adiaeresis 0x28
-#Adiaeresis 0x28 shift
-#dead_caron 0x28 shift altgr
-#asciicircum 0x29
-acute 0x28
-dead_acute 0x28
-#dead_circumflex 0x29
-#degree 0x29 shift
-#notsign 0x29 altgr
-plus 0x2b
-asterisk 0x2b shift
-grave 0x2b altgr
-#numbersign 0x2b
-#apostrophe 0x2b shift
-#dead_breve 0x2b shift altgr
-#y 0x2c addupper
-guillemotleft 0x2c altgr
-guillemotright 0x2d altgr
-cent 0x2e altgr
-copyright 0x2e shift altgr
-leftdoublequotemark 0x2f altgr
-rightdoublequotemark 0x30 altgr
-mu 0x32 altgr
-masculine 0x32 shift altgr
-comma 0x33
-semicolon 0x33 shift
-horizconnector 0x33 altgr
-multiply 0x33 shift altgr
-period 0x34
-colon 0x34 shift
-periodcentered 0x34 altgr
-division 0x34 shift altgr
-#minus 0x35
-#underscore 0x35 shift
-thorn 0x35
-THORN 0x35 shift
-dead_belowdot 0x35 altgr
-dead_abovedot 0x35 shift altgr
-
+++ /dev/null
-# generated from XKB map it
-include common
-map 0x410
-exclam 0x02 shift
-onesuperior 0x02 altgr
-exclamdown 0x02 shift altgr
-quotedbl 0x03 shift
-twosuperior 0x03 altgr
-oneeighth 0x03 shift altgr
-sterling 0x04 shift
-threesuperior 0x04 altgr
-dollar 0x05 shift
-onequarter 0x05 altgr
-percent 0x06 shift
-onehalf 0x06 altgr
-threeeighths 0x06 shift altgr
-ampersand 0x07 shift
-threequarters 0x07 altgr
-fiveeighths 0x07 shift altgr
-slash 0x08 shift
-braceleft 0x08 altgr
-seveneighths 0x08 shift altgr
-parenleft 0x09 shift
-trademark 0x09 shift altgr
-parenright 0x0a shift
-plusminus 0x0a shift altgr
-equal 0x0b shift
-braceright 0x0b altgr
-degree 0x0b shift altgr
-apostrophe 0x0c
-question 0x0c shift
-grave 0x0c altgr
-questiondown 0x0c shift altgr
-igrave 0x0d
-asciicircum 0x0d shift
-asciitilde 0x0d altgr
-dead_ogonek 0x0d shift altgr
-at 0x10 altgr
-Greek_OMEGA 0x10 shift altgr
-lstroke 0x11 altgr
-Lstroke 0x11 shift altgr
-EuroSign 0x12 altgr
-cent 0x12 shift altgr
-paragraph 0x13 altgr
-registered 0x13 shift altgr
-tslash 0x14 altgr
-Tslash 0x14 shift altgr
-leftarrow 0x15 altgr
-yen 0x15 shift altgr
-downarrow 0x16 altgr
-uparrow 0x16 shift altgr
-rightarrow 0x17 altgr
-idotless 0x17 shift altgr
-oslash 0x18 altgr
-Ooblique 0x18 shift altgr
-thorn 0x19 altgr
-THORN 0x19 shift altgr
-egrave 0x1a
-eacute 0x1a shift
-bracketleft 0x1a altgr
-dead_abovering 0x1a shift altgr
-plus 0x1b
-asterisk 0x1b shift
-bracketright 0x1b altgr
-dead_macron 0x1b shift altgr
-ae 0x1e altgr
-AE 0x1e shift altgr
-ssharp 0x1f altgr
-section 0x1f shift altgr
-eth 0x20 altgr
-ETH 0x20 shift altgr
-dstroke 0x21 altgr
-ordfeminine 0x21 shift altgr
-eng 0x22 altgr
-ENG 0x22 shift altgr
-hstroke 0x23 altgr
-Hstroke 0x23 shift altgr
-kra 0x25 altgr
-lstroke 0x26 altgr
-Lstroke 0x26 shift altgr
-ograve 0x27
-ccedilla 0x27 shift
-at 0x27 altgr
-dead_doubleacute 0x27 shift altgr
-agrave 0x28
-degree 0x28 shift
-numbersign 0x28 altgr
-backslash 0x29
-bar 0x29 shift
-notsign 0x29 altgr
-ugrave 0x2b
-section 0x2b shift
-dead_grave 0x2b altgr
-dead_breve 0x2b shift altgr
-guillemotleft 0x2c altgr
-guillemotright 0x2d altgr
-cent 0x2e altgr
-copyright 0x2e shift altgr
-leftdoublequotemark 0x2f altgr
-grave 0x2f shift altgr
-rightdoublequotemark 0x30 altgr
-mu 0x32 altgr
-masculine 0x32 shift altgr
-comma 0x33
-semicolon 0x33 shift
-horizconnector 0x33 altgr
-multiply 0x33 shift altgr
-period 0x34
-colon 0x34 shift
-periodcentered 0x34 altgr
-division 0x34 shift altgr
-minus 0x35
-underscore 0x35 shift
-dead_belowdot 0x35 altgr
-dead_abovedot 0x35 shift altgr
+++ /dev/null
-# generated from XKB map jp106
-include common
-map 0x411
-exclam 0x02 shift
-kana_NU 0x02 altgr
-quotedbl 0x03 shift
-kana_FU 0x03 altgr
-numbersign 0x04 shift
-kana_A 0x04 altgr
-kana_a 0x04 shift altgr
-dollar 0x05 shift
-kana_U 0x05 altgr
-kana_u 0x05 shift altgr
-percent 0x06 shift
-kana_E 0x06 altgr
-kana_e 0x06 shift altgr
-ampersand 0x07 shift
-kana_O 0x07 altgr
-kana_o 0x07 shift altgr
-apostrophe 0x08 shift
-kana_YA 0x08 altgr
-kana_ya 0x08 shift altgr
-parenleft 0x09 shift
-kana_YU 0x09 altgr
-kana_yu 0x09 shift altgr
-parenright 0x0a shift
-kana_YO 0x0a altgr
-kana_yo 0x0a shift altgr
-asciitilde 0x0b shift
-kana_WA 0x0b altgr
-kana_WO 0x0b shift altgr
-minus 0x0c
-equal 0x0c shift
-kana_HO 0x0c altgr
-asciicircum 0x0d
-asciitilde 0x0d shift
-kana_HE 0x0d altgr
-kana_TA 0x10 altgr
-kana_TE 0x11 altgr
-kana_I 0x12 altgr
-kana_i 0x12 shift altgr
-kana_SU 0x13 altgr
-kana_KA 0x14 altgr
-kana_N 0x15 altgr
-kana_NA 0x16 altgr
-kana_NI 0x17 altgr
-kana_RA 0x18 altgr
-kana_SE 0x19 altgr
-at 0x1a
-grave 0x1a shift
-voicedsound 0x1a altgr
-bracketleft 0x1b
-braceleft 0x1b shift
-semivoicedsound 0x1b altgr
-kana_openingbracket 0x1b shift altgr
-kana_CHI 0x1e altgr
-kana_TO 0x1f altgr
-kana_SHI 0x20 altgr
-kana_HA 0x21 altgr
-kana_KI 0x22 altgr
-kana_KU 0x23 altgr
-kana_MA 0x24 altgr
-kana_NO 0x25 altgr
-kana_RI 0x26 altgr
-semicolon 0x27
-plus 0x27 shift
-kana_RE 0x27 altgr
-colon 0x28
-asterisk 0x28 shift
-kana_KE 0x28 altgr
-Zenkaku_Hankaku 0x29
-bracketright 0x2b
-braceright 0x2b shift
-kana_MU 0x2b altgr
-kana_closingbracket 0x2b shift altgr
-kana_TSU 0x2c altgr
-kana_tsu 0x2c shift altgr
-kana_SA 0x2d altgr
-kana_SO 0x2e altgr
-kana_HI 0x2f altgr
-kana_KO 0x30 altgr
-kana_MI 0x31 altgr
-kana_MO 0x32 altgr
-comma 0x33
-less 0x33 shift
-kana_NE 0x33 altgr
-kana_comma 0x33 shift altgr
-period 0x34
-greater 0x34 shift
-kana_RU 0x34 altgr
-kana_fullstop 0x34 shift altgr
-slash 0x35
-question 0x35 shift
-kana_ME 0x35 altgr
-kana_conjunctive 0x35 shift altgr
-Eisu_toggle 0x3a shift
-Execute 0x54 shift
-Kanji 0x70
-backslash 0x73
-bar 0x7d shift
-underscore 0x73 shift
-Henkan_Mode 0x79
-Katakana 0x70
-Muhenkan 0x7b
+++ /dev/null
-# generated from XKB map lt
-include common
-map 0x427
-exclam 0x02 shift
-aogonek 0x02 altgr
-Aogonek 0x02 shift altgr
-at 0x03 shift
-ccaron 0x03 altgr
-Ccaron 0x03 shift altgr
-numbersign 0x04 shift
-eogonek 0x04 altgr
-Eogonek 0x04 shift altgr
-dollar 0x05 shift
-eabovedot 0x05 altgr
-Eabovedot 0x05 shift altgr
-percent 0x06 shift
-iogonek 0x06 altgr
-Iogonek 0x06 shift altgr
-asciicircum 0x07 shift
-scaron 0x07 altgr
-Scaron 0x07 shift altgr
-ampersand 0x08 shift
-uogonek 0x08 altgr
-Uogonek 0x08 shift altgr
-asterisk 0x09 shift
-umacron 0x09 altgr
-Umacron 0x09 shift altgr
-parenleft 0x0a shift
-doublelowquotemark 0x0a altgr
-parenright 0x0b shift
-leftdoublequotemark 0x0b altgr
-minus 0x0c
-underscore 0x0c shift
-equal 0x0d
-plus 0x0d shift
-zcaron 0x0d altgr
-Zcaron 0x0d shift altgr
-bracketleft 0x1a
-braceleft 0x1a shift
-bracketright 0x1b
-braceright 0x1b shift
-semicolon 0x27
-colon 0x27 shift
-apostrophe 0x28
-quotedbl 0x28 shift
-grave 0x29
-asciitilde 0x29 shift
-backslash 0x2b
-bar 0x2b shift
-comma 0x33
-less 0x33 shift
-period 0x34
-greater 0x34 shift
-slash 0x35
-question 0x35 shift
-endash 0x56
-EuroSign 0x56 shift
+++ /dev/null
-# generated from XKB map lv
-include common
-map 0x426
-exclam 0x02 shift
-onesuperior 0x02 altgr
-exclamdown 0x02 shift altgr
-at 0x03 shift
-twosuperior 0x03 altgr
-oneeighth 0x03 shift altgr
-numbersign 0x04 shift
-threesuperior 0x04 altgr
-sterling 0x04 shift altgr
-dollar 0x05 shift
-EuroSign 0x05 altgr
-cent 0x05 shift altgr
-percent 0x06 shift
-onehalf 0x06 altgr
-threeeighths 0x06 shift altgr
-asciicircum 0x07 shift
-threequarters 0x07 altgr
-fiveeighths 0x07 shift altgr
-ampersand 0x08 shift
-braceleft 0x08 altgr
-seveneighths 0x08 shift altgr
-asterisk 0x09 shift
-bracketleft 0x09 altgr
-trademark 0x09 shift altgr
-parenleft 0x0a shift
-bracketright 0x0a altgr
-plusminus 0x0a shift altgr
-parenright 0x0b shift
-braceright 0x0b altgr
-degree 0x0b shift altgr
-minus 0x0c
-underscore 0x0c shift
-backslash 0x0c altgr
-questiondown 0x0c shift altgr
-equal 0x0d
-plus 0x0d shift
-dead_cedilla 0x0d altgr
-dead_ogonek 0x0d shift altgr
-at 0x10 altgr
-Greek_OMEGA 0x10 shift altgr
-lstroke 0x11 altgr
-Lstroke 0x11 shift altgr
-emacron 0x12 altgr
-Emacron 0x12 shift altgr
-rcedilla 0x13 altgr
-Rcedilla 0x13 shift altgr
-tslash 0x14 altgr
-Tslash 0x14 shift altgr
-leftarrow 0x15 altgr
-yen 0x15 shift altgr
-umacron 0x16 altgr
-Umacron 0x16 shift altgr
-imacron 0x17 altgr
-Imacron 0x17 shift altgr
-omacron 0x18 altgr
-Omacron 0x18 shift altgr
-thorn 0x19 altgr
-THORN 0x19 shift altgr
-bracketleft 0x1a
-braceleft 0x1a shift
-dead_diaeresis 0x1a altgr
-dead_abovering 0x1a shift altgr
-bracketright 0x1b
-braceright 0x1b shift
-dead_tilde 0x1b altgr
-dead_macron 0x1b shift altgr
-ISO_Next_Group 0x1c shift
-amacron 0x1e altgr
-Amacron 0x1e shift altgr
-scaron 0x1f altgr
-Scaron 0x1f shift altgr
-eth 0x20 altgr
-ETH 0x20 shift altgr
-dstroke 0x21 altgr
-ordfeminine 0x21 shift altgr
-gcedilla 0x22 altgr
-Gcedilla 0x22 shift altgr
-hstroke 0x23 altgr
-Hstroke 0x23 shift altgr
-kcedilla 0x25 altgr
-Kcedilla 0x25 shift altgr
-lcedilla 0x26 altgr
-Lcedilla 0x26 shift altgr
-semicolon 0x27
-colon 0x27 shift
-dead_acute 0x27 altgr
-dead_doubleacute 0x27 shift altgr
-apostrophe 0x28
-quotedbl 0x28 shift
-leftdoublequotemark 0x28 altgr
-doublelowquotemark 0x28 shift altgr
-grave 0x29
-asciitilde 0x29 shift
-notsign 0x29 altgr
-backslash 0x2b
-bar 0x2b shift
-dead_grave 0x2b altgr
-dead_breve 0x2b shift altgr
-zcaron 0x2c altgr
-Zcaron 0x2c shift altgr
-guillemotright 0x2d altgr
-greater 0x2d shift altgr
-ccaron 0x2e altgr
-Ccaron 0x2e shift altgr
-leftdoublequotemark 0x2f altgr
-grave 0x2f shift altgr
-rightdoublequotemark 0x30 altgr
-apostrophe 0x30 shift altgr
-ncedilla 0x31 altgr
-Ncedilla 0x31 shift altgr
-mu 0x32 altgr
-masculine 0x32 shift altgr
-comma 0x33
-less 0x33 shift
-horizconnector 0x33 altgr
-multiply 0x33 shift altgr
-period 0x34
-greater 0x34 shift
-periodcentered 0x34 altgr
-division 0x34 shift altgr
-slash 0x35
-question 0x35 shift
-dead_belowdot 0x35 altgr
-dead_abovedot 0x35 shift altgr
-nobreakspace 0x39 altgr
+++ /dev/null
-# generated from XKB map mk
-include common
-map 0x42f
-exclam 0x02 shift
-at 0x03 shift
-doublelowquotemark 0x03 shift altgr
-numbersign 0x04 shift
-leftdoublequotemark 0x04 shift altgr
-dollar 0x05 shift
-percent 0x06 shift
-asciicircum 0x07 shift
-ampersand 0x08 shift
-asterisk 0x09 shift
-parenleft 0x0a shift
-parenright 0x0b shift
-minus 0x0c
-underscore 0x0c shift
-equal 0x0d
-plus 0x0d shift
-Cyrillic_lje 0x10 altgr
-Cyrillic_LJE 0x10 shift altgr
-Cyrillic_nje 0x11 altgr
-Cyrillic_NJE 0x11 shift altgr
-Cyrillic_ie 0x12 altgr
-Cyrillic_IE 0x12 shift altgr
-Cyrillic_er 0x13 altgr
-Cyrillic_ER 0x13 shift altgr
-Cyrillic_te 0x14 altgr
-Cyrillic_TE 0x14 shift altgr
-Macedonia_dse 0x15 altgr
-Macedonia_DSE 0x15 shift altgr
-Cyrillic_u 0x16 altgr
-Cyrillic_U 0x16 shift altgr
-Cyrillic_i 0x17 altgr
-Cyrillic_I 0x17 shift altgr
-Cyrillic_o 0x18 altgr
-Cyrillic_O 0x18 shift altgr
-Cyrillic_pe 0x19 altgr
-Cyrillic_PE 0x19 shift altgr
-bracketleft 0x1a
-braceleft 0x1a shift
-Cyrillic_sha 0x1a altgr
-Cyrillic_SHA 0x1a shift altgr
-bracketright 0x1b
-braceright 0x1b shift
-Macedonia_gje 0x1b altgr
-Macedonia_GJE 0x1b shift altgr
-Cyrillic_a 0x1e altgr
-Cyrillic_A 0x1e shift altgr
-Cyrillic_es 0x1f altgr
-Cyrillic_ES 0x1f shift altgr
-Cyrillic_de 0x20 altgr
-Cyrillic_DE 0x20 shift altgr
-Cyrillic_ef 0x21 altgr
-Cyrillic_EF 0x21 shift altgr
-Cyrillic_ghe 0x22 altgr
-Cyrillic_GHE 0x22 shift altgr
-Cyrillic_ha 0x23 altgr
-Cyrillic_HA 0x23 shift altgr
-Cyrillic_je 0x24 altgr
-Cyrillic_JE 0x24 shift altgr
-Cyrillic_ka 0x25 altgr
-Cyrillic_KA 0x25 shift altgr
-Cyrillic_el 0x26 altgr
-Cyrillic_EL 0x26 shift altgr
-semicolon 0x27
-colon 0x27 shift
-Cyrillic_che 0x27 altgr
-Cyrillic_CHE 0x27 shift altgr
-apostrophe 0x28
-quotedbl 0x28 shift
-Macedonia_kje 0x28 altgr
-Macedonia_KJE 0x28 shift altgr
-grave 0x29
-asciitilde 0x29 shift
-backslash 0x2b
-bar 0x2b shift
-Cyrillic_zhe 0x2b altgr
-Cyrillic_ZHE 0x2b shift altgr
-Cyrillic_ze 0x2c altgr
-Cyrillic_ZE 0x2c shift altgr
-Cyrillic_dzhe 0x2d altgr
-Cyrillic_DZHE 0x2d shift altgr
-Cyrillic_tse 0x2e altgr
-Cyrillic_TSE 0x2e shift altgr
-Cyrillic_ve 0x2f altgr
-Cyrillic_VE 0x2f shift altgr
-Cyrillic_be 0x30 altgr
-Cyrillic_BE 0x30 shift altgr
-Cyrillic_en 0x31 altgr
-Cyrillic_EN 0x31 shift altgr
-Cyrillic_em 0x32 altgr
-Cyrillic_EM 0x32 shift altgr
-comma 0x33
-less 0x33 shift
-semicolon 0x33 shift altgr
-period 0x34
-greater 0x34 shift
-colon 0x34 shift altgr
-slash 0x35
-question 0x35 shift
+++ /dev/null
-Shift_R 0x36
-Shift_L 0x2a
-
-Alt_R 0xb8
-Mode_switch 0xb8
-Alt_L 0x38
-
-Control_R 0x9d
-Control_L 0x1d
-
-# Translate Super to Windows keys.
-# This is hardcoded. See documentation for details.
-Super_R 0xdb
-Super_L 0xdc
-
-# Translate Menu to the Windows Application key.
-Menu 0xdd
+++ /dev/null
-# Dutch (Netherlands)
-include common
-map 0x413
-
-exclam 0x02 shift
-onesuperior 0x02 altgr
-quotebl 0x03 shift
-twosuperior 0x03 altgr
-numbersign 0x04 shift
-threesuperior 0x04 altgr
-dollar 0x05 shift
-onequarter 0x05 altgr
-percent 0x06 shift
-onehalf 0x06 altgr
-ampersand 0x07 shift
-threequarters 0x07 altgr
-underscore 0x08 shift
-sterling 0x08 altgr
-parenleft 0x09 shift
-braceleft 0x09 altgr
-parenright 0x0a shift
-braceright 0x0a altgr
-apostrophe 0x0b shift
-slash 0x0c
-question 0x0c shift
-backslash 0x0c altgr
-degree 0x0d
-dead_tilde 0x0d shift
-dead_cedilla 0x0d altgr
-EuroSign 0x12 altgr
-paragraph 0x13 altgr
-dead_diaeresis 0x1a
-dead_circumflex 0x1a shift
-asterisk 0x1b
-bar 0x1b shift
-ssharp 0x1f altgr
-plus 0x27
-plusminus 0x27 shift
-dead_acute 0x28
-dead_grave 0x28 shift
-at 0x29
-section 0x29 shift
-notsign 0x29 altgr
-less 0x2b
-greater 0x2b shift
-guillemotleft 0x2c altgr
-guillemotright 0x2d altgr
-copyright 0x2e altgr
-mu 0x32 altgr
-comma 0x33
-semicolon 0x33 shift
-period 0x34
-colon 0x34 shift
-periodcentered 0x34 altgr
-hyphen 0x35
-equal 0x35 shift
-bracketright 0x56
-bracketleft 0x56 shift
-brokenbar 0x56 altgr
-
+++ /dev/null
-# Dutch (Belgium)
-map 0x813
-include common
+++ /dev/null
-# generated from XKB map no
-include common
-map 0x414
-exclam 0x02 shift
-exclamdown 0x02 altgr
-onesuperior 0x02 shift altgr
-quotedbl 0x03 shift
-at 0x03 altgr
-twosuperior 0x03 shift altgr
-numbersign 0x04 shift
-sterling 0x04 altgr
-threesuperior 0x04 shift altgr
-currency 0x05 shift
-dollar 0x05 altgr
-onequarter 0x05 shift altgr
-percent 0x06 shift
-onehalf 0x06 altgr
-cent 0x06 shift altgr
-ampersand 0x07 shift
-yen 0x07 altgr
-fiveeighths 0x07 shift altgr
-slash 0x08 shift
-braceleft 0x08 altgr
-division 0x08 shift altgr
-parenleft 0x09 shift
-bracketleft 0x09 altgr
-guillemotleft 0x09 shift altgr
-parenright 0x0a shift
-bracketright 0x0a altgr
-guillemotright 0x0a shift altgr
-equal 0x0b shift
-braceright 0x0b altgr
-degree 0x0b shift altgr
-plus 0x0c
-question 0x0c shift
-plusminus 0x0c altgr
-questiondown 0x0c shift altgr
-backslash 0x0d
-dead_grave 0x0d shift
-dead_acute 0x0d altgr
-notsign 0x0d shift altgr
-Greek_OMEGA 0x10 shift altgr
-lstroke 0x11 altgr
-Lstroke 0x11 shift altgr
-EuroSign 0x12 altgr
-cent 0x12 shift altgr
-registered 0x13 altgr
-thorn 0x14 altgr
-THORN 0x14 shift altgr
-leftarrow 0x15 altgr
-yen 0x15 shift altgr
-downarrow 0x16 altgr
-uparrow 0x16 shift altgr
-rightarrow 0x17 altgr
-idotless 0x17 shift altgr
-oe 0x18 altgr
-OE 0x18 shift altgr
-thorn 0x19 altgr
-THORN 0x19 shift altgr
-aring 0x1a
-Aring 0x1a shift
-dead_diaeresis 0x1a altgr
-dead_abovering 0x1a shift altgr
-dead_diaeresis 0x1b
-dead_circumflex 0x1b shift
-asciicircum 0x01b shift
-dead_tilde 0x1b altgr
-asciitilde 0x1b altgr
-dead_caron 0x1b shift altgr
-ordfeminine 0x1e altgr
-masculine 0x1e shift altgr
-ssharp 0x1f altgr
-section 0x1f shift altgr
-eth 0x20 altgr
-ETH 0x20 shift altgr
-dstroke 0x21 altgr
-ordfeminine 0x21 shift altgr
-eng 0x22 altgr
-ENG 0x22 shift altgr
-hstroke 0x23 altgr
-Hstroke 0x23 shift altgr
-kra 0x25 altgr
-lstroke 0x26 altgr
-Lstroke 0x26 shift altgr
-oslash 0x27
-Ooblique 0x27 shift
-dead_doubleacute 0x27 shift altgr
-ae 0x28
-AE 0x28 shift
-dead_caron 0x28 shift altgr
-bar 0x29
-section 0x29 shift
-brokenbar 0x29 altgr
-paragraph 0x29 shift altgr
-apostrophe 0x2b
-asterisk 0x2b shift
-multiply 0x2b shift altgr
-guillemotleft 0x2c altgr
-guillemotright 0x2d altgr
-copyright 0x2e altgr
-leftdoublequotemark 0x2f altgr
-rightdoublequotemark 0x30 altgr
-mu 0x32 altgr
-masculine 0x32 shift altgr
-comma 0x33
-semicolon 0x33 shift
-dead_cedilla 0x33 altgr
-dead_ogonek 0x33 shift altgr
-period 0x34
-colon 0x34 shift
-periodcentered 0x34 altgr
-dead_abovedot 0x34 shift altgr
-minus 0x35
-underscore 0x35 shift
-hyphen 0x35 altgr
-macron 0x35 shift altgr
-nobreakspace 0x39 altgr
-onehalf 0x56 altgr
-threequarters 0x56 shift altgr
+++ /dev/null
-# generated from XKB map pl
-include common
-map 0x415
-exclam 0x02 shift
-onesuperior 0x02 altgr
-exclamdown 0x02 shift altgr
-at 0x03 shift
-twosuperior 0x03 altgr
-oneeighth 0x03 shift altgr
-numbersign 0x04 shift
-threesuperior 0x04 altgr
-sterling 0x04 shift altgr
-dollar 0x05 shift
-onequarter 0x05 altgr
-percent 0x06 shift
-onehalf 0x06 altgr
-threeeighths 0x06 shift altgr
-asciicircum 0x07 shift
-threequarters 0x07 altgr
-fiveeighths 0x07 shift altgr
-ampersand 0x08 shift
-braceleft 0x08 altgr
-seveneighths 0x08 shift altgr
-asterisk 0x09 shift
-bracketleft 0x09 altgr
-trademark 0x09 shift altgr
-parenleft 0x0a shift
-bracketright 0x0a altgr
-plusminus 0x0a shift altgr
-parenright 0x0b shift
-braceright 0x0b altgr
-degree 0x0b shift altgr
-minus 0x0c
-underscore 0x0c shift
-backslash 0x0c altgr
-questiondown 0x0c shift altgr
-equal 0x0d
-plus 0x0d shift
-dead_cedilla 0x0d altgr
-dead_ogonek 0x0d shift altgr
-Greek_OMEGA 0x10 shift altgr
-lstroke 0x11 altgr
-Lstroke 0x11 shift altgr
-eogonek 0x12 altgr
-Eogonek 0x12 shift altgr
-paragraph 0x13 altgr
-registered 0x13 shift altgr
-tslash 0x14 altgr
-Tslash 0x14 shift altgr
-leftarrow 0x15 altgr
-yen 0x15 shift altgr
-EuroSign 0x16 altgr
-uparrow 0x16 shift altgr
-rightarrow 0x17 altgr
-idotless 0x17 shift altgr
-oacute 0x18 altgr
-Oacute 0x18 shift altgr
-thorn 0x19 altgr
-THORN 0x19 shift altgr
-bracketleft 0x1a
-braceleft 0x1a shift
-dead_diaeresis 0x1a altgr
-dead_abovering 0x1a shift altgr
-bracketright 0x1b
-braceright 0x1b shift
-dead_tilde 0x1b altgr
-dead_macron 0x1b shift altgr
-aogonek 0x1e altgr
-Aogonek 0x1e shift altgr
-sacute 0x1f altgr
-Sacute 0x1f shift altgr
-eth 0x20 altgr
-ETH 0x20 shift altgr
-dstroke 0x21 altgr
-ordfeminine 0x21 shift altgr
-eng 0x22 altgr
-ENG 0x22 shift altgr
-hstroke 0x23 altgr
-Hstroke 0x23 shift altgr
-kra 0x25 altgr
-lstroke 0x26 altgr
-Lstroke 0x26 shift altgr
-semicolon 0x27
-colon 0x27 shift
-dead_acute 0x27 altgr
-dead_doubleacute 0x27 shift altgr
-apostrophe 0x28
-quotedbl 0x28 shift
-dead_circumflex 0x28 altgr
-dead_caron 0x28 shift altgr
-grave 0x29
-asciitilde 0x29 shift
-notsign 0x29 altgr
-backslash 0x2b
-bar 0x2b shift
-dead_grave 0x2b altgr
-dead_breve 0x2b shift altgr
-zabovedot 0x2c altgr
-Zabovedot 0x2c shift altgr
-zacute 0x2d altgr
-Zacute 0x2d shift altgr
-cacute 0x2e altgr
-Cacute 0x2e shift altgr
-leftdoublequotemark 0x2f altgr
-grave 0x2f shift altgr
-rightdoublequotemark 0x30 altgr
-nacute 0x31 altgr
-Nacute 0x31 shift altgr
-mu 0x32 altgr
-masculine 0x32 shift altgr
-comma 0x33
-less 0x33 shift
-horizconnector 0x33 altgr
-multiply 0x33 shift altgr
-period 0x34
-greater 0x34 shift
-periodcentered 0x34 altgr
-division 0x34 shift altgr
-slash 0x35
-question 0x35 shift
-dead_belowdot 0x35 altgr
-dead_abovedot 0x35 shift altgr
+++ /dev/null
-# generated from XKB map pt
-include common
-map 0x816
-exclam 0x02 shift
-onesuperior 0x02 altgr
-exclamdown 0x02 shift altgr
-quotedbl 0x03 shift
-at 0x03 altgr
-oneeighth 0x03 shift altgr
-numbersign 0x04 shift
-sterling 0x04 altgr
-dollar 0x05 shift
-section 0x05 altgr
-percent 0x06 shift
-onehalf 0x06 altgr
-threeeighths 0x06 shift altgr
-ampersand 0x07 shift
-threequarters 0x07 altgr
-fiveeighths 0x07 shift altgr
-slash 0x08 shift
-braceleft 0x08 altgr
-seveneighths 0x08 shift altgr
-parenleft 0x09 shift
-bracketleft 0x09 altgr
-trademark 0x09 shift altgr
-parenright 0x0a shift
-bracketright 0x0a altgr
-plusminus 0x0a shift altgr
-equal 0x0b shift
-braceright 0x0b altgr
-degree 0x0b shift altgr
-apostrophe 0x0c
-question 0x0c shift
-backslash 0x0c altgr
-questiondown 0x0c shift altgr
-guillemotleft 0x0d
-guillemotright 0x0d shift
-dead_cedilla 0x0d altgr
-dead_ogonek 0x0d shift altgr
-Greek_OMEGA 0x10 shift altgr
-lstroke 0x11 altgr
-Lstroke 0x11 shift altgr
-EuroSign 0x12 altgr
-cent 0x12 shift altgr
-paragraph 0x13 altgr
-registered 0x13 shift altgr
-tslash 0x14 altgr
-Tslash 0x14 shift altgr
-leftarrow 0x15 altgr
-yen 0x15 shift altgr
-downarrow 0x16 altgr
-uparrow 0x16 shift altgr
-rightarrow 0x17 altgr
-idotless 0x17 shift altgr
-oslash 0x18 altgr
-Ooblique 0x18 shift altgr
-thorn 0x19 altgr
-THORN 0x19 shift altgr
-plus 0x1a
-asterisk 0x1a shift
-dead_diaeresis 0x1a altgr
-dead_abovering 0x1a shift altgr
-dead_acute 0x1b
-dead_grave 0x1b shift
-dead_tilde 0x1b altgr
-dead_macron 0x1b shift altgr
-ae 0x1e altgr
-AE 0x1e shift altgr
-ssharp 0x1f altgr
-eth 0x20 altgr
-ETH 0x20 shift altgr
-dstroke 0x21 altgr
-ordfeminine 0x21 shift altgr
-eng 0x22 altgr
-ENG 0x22 shift altgr
-hstroke 0x23 altgr
-Hstroke 0x23 shift altgr
-kra 0x25 altgr
-lstroke 0x26 altgr
-Lstroke 0x26 shift altgr
-ccedilla 0x27
-Ccedilla 0x27 shift
-dead_doubleacute 0x27 shift altgr
-masculine 0x28
-ordfeminine 0x28 shift
-dead_circumflex 0x28 altgr
-dead_caron 0x28 shift altgr
-backslash 0x29
-bar 0x29 shift
-notsign 0x29 altgr
-dead_tilde 0x2b
-dead_circumflex 0x2b shift
-dead_breve 0x2b shift altgr
-less 0x56
-greater 0x56 shift
-cent 0x2e altgr
-copyright 0x2e shift altgr
-leftdoublequotemark 0x2f altgr
-grave 0x2f shift altgr
-rightdoublequotemark 0x30 altgr
-mu 0x32 altgr
-comma 0x33
-semicolon 0x33 shift
-horizconnector 0x33 altgr
-multiply 0x33 shift altgr
-period 0x34
-colon 0x34 shift
-periodcentered 0x34 altgr
-division 0x34 shift altgr
-minus 0x35
-underscore 0x35 shift
-dead_belowdot 0x35 altgr
-dead_abovedot 0x35 shift altgr
+++ /dev/null
-# generated from XKB map br
-include common
-map 0x416
-exclam 0x02 shift
-onesuperior 0x02 altgr
-exclamdown 0x02 shift altgr
-at 0x03 shift
-twosuperior 0x03 altgr
-onehalf 0x03 shift altgr
-numbersign 0x04 shift
-threesuperior 0x04 altgr
-threequarters 0x04 shift altgr
-dollar 0x05 shift
-sterling 0x05 altgr
-onequarter 0x05 shift altgr
-percent 0x06 shift
-cent 0x06 altgr
-dead_diaeresis 0x07 shift
-notsign 0x07 altgr
-diaeresis 0x07 shift altgr
-ampersand 0x08 shift
-braceleft 0x08 altgr
-asterisk 0x09 shift
-bracketleft 0x09 altgr
-parenleft 0x0a shift
-bracketright 0x0a altgr
-parenright 0x0b shift
-braceright 0x0b altgr
-minus 0x0c
-underscore 0x0c shift
-backslash 0x0c altgr
-equal 0x0d
-plus 0x0d shift
-section 0x0d altgr
-EuroSign 0x12 altgr
-registered 0x13 altgr
-dead_acute 0x1a
-dead_grave 0x1a shift
-acute 0x1a altgr
-grave 0x1a shift altgr
-bracketleft 0x1b
-braceleft 0x1b shift
-ordfeminine 0x1b altgr
-ccedilla 0x27
-Ccedilla 0x27 shift
-dead_tilde 0x28
-dead_circumflex 0x28 shift
-asciitilde 0x28 altgr
-asciicircum 0x28 shift altgr
-apostrophe 0x29
-quotedbl 0x29 shift
-bracketright 0x2b
-braceright 0x2b shift
-masculine 0x2b altgr
-copyright 0x2e altgr
-mu 0x32 altgr
-comma 0x33
-less 0x33 shift
-period 0x34
-greater 0x34 shift
-semicolon 0x35
-colon 0x35 shift
-comma 0x53 numlock
-backslash 0x56
-bar 0x56 shift
-slash 0x73
-question 0x73 shift
-degree 0x73 altgr
-KP_Decimal 0x34
+++ /dev/null
-# generated from XKB map ru
-include common
-map 0x419
-exclam 0x02 shift
-at 0x03 shift
-quotedbl 0x03 shift altgr
-numbersign 0x04 shift
-dollar 0x05 shift
-asterisk 0x05 shift altgr
-percent 0x06 shift
-colon 0x06 shift altgr
-asciicircum 0x07 shift
-comma 0x07 shift altgr
-ampersand 0x08 shift
-period 0x08 shift altgr
-asterisk 0x09 shift
-semicolon 0x09 shift altgr
-parenleft 0x0a shift
-parenright 0x0b shift
-minus 0x0c
-underscore 0x0c shift
-equal 0x0d
-plus 0x0d shift
-Cyrillic_shorti 0x10 altgr
-Cyrillic_SHORTI 0x10 shift altgr
-Cyrillic_tse 0x11 altgr
-Cyrillic_TSE 0x11 shift altgr
-Cyrillic_u 0x12 altgr
-Cyrillic_U 0x12 shift altgr
-Cyrillic_ka 0x13 altgr
-Cyrillic_KA 0x13 shift altgr
-Cyrillic_ie 0x14 altgr
-Cyrillic_IE 0x14 shift altgr
-Cyrillic_en 0x15 altgr
-Cyrillic_EN 0x15 shift altgr
-Cyrillic_ghe 0x16 altgr
-Cyrillic_GHE 0x16 shift altgr
-Cyrillic_sha 0x17 altgr
-Cyrillic_SHA 0x17 shift altgr
-Cyrillic_shcha 0x18 altgr
-Cyrillic_SHCHA 0x18 shift altgr
-Cyrillic_ze 0x19 altgr
-Cyrillic_ZE 0x19 shift altgr
-bracketleft 0x1a
-braceleft 0x1a shift
-Cyrillic_ha 0x1a altgr
-Cyrillic_HA 0x1a shift altgr
-bracketright 0x1b
-braceright 0x1b shift
-Cyrillic_hardsign 0x1b altgr
-Cyrillic_HARDSIGN 0x1b shift altgr
-Cyrillic_ef 0x1e altgr
-Cyrillic_EF 0x1e shift altgr
-Cyrillic_yeru 0x1f altgr
-Cyrillic_YERU 0x1f shift altgr
-Cyrillic_ve 0x20 altgr
-Cyrillic_VE 0x20 shift altgr
-Cyrillic_a 0x21 altgr
-Cyrillic_A 0x21 shift altgr
-Cyrillic_pe 0x22 altgr
-Cyrillic_PE 0x22 shift altgr
-Cyrillic_er 0x23 altgr
-Cyrillic_ER 0x23 shift altgr
-Cyrillic_o 0x24 altgr
-Cyrillic_O 0x24 shift altgr
-Cyrillic_el 0x25 altgr
-Cyrillic_EL 0x25 shift altgr
-Cyrillic_de 0x26 altgr
-Cyrillic_DE 0x26 shift altgr
-semicolon 0x27
-colon 0x27 shift
-Cyrillic_zhe 0x27 altgr
-Cyrillic_ZHE 0x27 shift altgr
-apostrophe 0x28
-quotedbl 0x28 shift
-Cyrillic_e 0x28 altgr
-Cyrillic_E 0x28 shift altgr
-grave 0x29
-asciitilde 0x29 shift
-Cyrillic_io 0x29 altgr
-Cyrillic_IO 0x29 shift altgr
-backslash 0x2b
-bar 0x2b shift
-Cyrillic_ya 0x2c altgr
-Cyrillic_YA 0x2c shift altgr
-Cyrillic_che 0x2d altgr
-Cyrillic_CHE 0x2d shift altgr
-Cyrillic_es 0x2e altgr
-Cyrillic_ES 0x2e shift altgr
-Cyrillic_em 0x2f altgr
-Cyrillic_EM 0x2f shift altgr
-Cyrillic_i 0x30 altgr
-Cyrillic_I 0x30 shift altgr
-Cyrillic_te 0x31 altgr
-Cyrillic_TE 0x31 shift altgr
-Cyrillic_softsign 0x32 altgr
-Cyrillic_SOFTSIGN 0x32 shift altgr
-comma 0x33
-less 0x33 shift
-Cyrillic_be 0x33 altgr
-Cyrillic_BE 0x33 shift altgr
-period 0x34
-greater 0x34 shift
-Cyrillic_yu 0x34 altgr
-Cyrillic_YU 0x34 shift altgr
-slash 0x35
-question 0x35 shift
-slash 0x56 altgr
-bar 0x56 shift altgr
+++ /dev/null
-# generated from XKB map sl
-include common
-map 0x424
-exclam 0x02 shift
-asciitilde 0x02 altgr
-dead_tilde 0x02 shift altgr
-quotedbl 0x03 shift
-dead_caron 0x03 altgr
-caron 0x03 shift altgr
-numbersign 0x04 shift
-asciicircum 0x04 altgr
-dead_circumflex 0x04 shift altgr
-dollar 0x05 shift
-dead_breve 0x05 altgr
-breve 0x05 shift altgr
-percent 0x06 shift
-degree 0x06 altgr
-dead_abovering 0x06 shift altgr
-ampersand 0x07 shift
-dead_ogonek 0x07 altgr
-ogonek 0x07 shift altgr
-slash 0x08 shift
-grave 0x08 altgr
-dead_grave 0x08 shift altgr
-parenleft 0x09 shift
-dead_abovedot 0x09 altgr
-abovedot 0x09 shift altgr
-parenright 0x0a shift
-dead_acute 0x0a altgr
-equal 0x0b shift
-dead_doubleacute 0x0b altgr
-doubleacute 0x0b shift altgr
-apostrophe 0x0c
-question 0x0c shift
-dead_diaeresis 0x0c altgr
-diaeresis 0x0c shift altgr
-plus 0x0d
-asterisk 0x0d shift
-dead_cedilla 0x0d altgr
-cedilla 0x0d shift altgr
-backslash 0x10 altgr
-Greek_OMEGA 0x10 shift altgr
-bar 0x11 altgr
-Lstroke 0x11 shift altgr
-EuroSign 0x12 altgr
-paragraph 0x13 altgr
-registered 0x13 shift altgr
-tslash 0x14 altgr
-Tslash 0x14 shift altgr
-z 0x15 addupper
-leftarrow 0x15 altgr
-yen 0x15 shift altgr
-downarrow 0x16 altgr
-uparrow 0x16 shift altgr
-rightarrow 0x17 altgr
-idotless 0x17 shift altgr
-oslash 0x18 altgr
-Ooblique 0x18 shift altgr
-thorn 0x19 altgr
-THORN 0x19 shift altgr
-scaron 0x1a
-Scaron 0x1a shift
-division 0x1a altgr
-dstroke 0x1b
-Dstroke 0x1b shift
-multiply 0x1b altgr
-dead_macron 0x1b shift altgr
-ae 0x1e altgr
-AE 0x1e shift altgr
-ssharp 0x1f altgr
-section 0x1f shift altgr
-eth 0x20 altgr
-ETH 0x20 shift altgr
-bracketleft 0x21 altgr
-ordfeminine 0x21 shift altgr
-bracketright 0x22 altgr
-ENG 0x22 shift altgr
-hstroke 0x23 altgr
-Hstroke 0x23 shift altgr
-lstroke 0x25 altgr
-Lstroke 0x26 altgr
-ccaron 0x27
-Ccaron 0x27 shift
-cacute 0x28
-Cacute 0x28 shift
-ssharp 0x28 altgr
-dead_cedilla 0x29
-notsign 0x29 altgr
-zcaron 0x2b
-Zcaron 0x2b shift
-currency 0x2b altgr
-y 0x2c addupper
-guillemotleft 0x2c altgr
-guillemotright 0x2d altgr
-cent 0x2e altgr
-copyright 0x2e shift altgr
-at 0x2f altgr
-braceleft 0x30 altgr
-braceright 0x31 altgr
-section 0x32 altgr
-masculine 0x32 shift altgr
-comma 0x33
-semicolon 0x33 shift
-horizconnector 0x33 altgr
-period 0x34
-colon 0x34 shift
-periodcentered 0x34 altgr
-minus 0x35
-underscore 0x35 shift
-dead_belowdot 0x35 altgr
+++ /dev/null
-map 0x0000041d
-include common
-
-#
-# Top row
-#
-section 0x29
-onehalf 0x29 shift
-
-# 1
-exclam 0x2 shift
-
-# 2
-quotedbl 0x3 shift
-at 0x3 altgr
-
-# 3
-numbersign 0x4 shift
-sterling 0x4 altgr
-# 4
-currency 0x5 shift
-dollar 0x5 altgr
-# 5
-percent 0x6 shift
-# 6
-ampersand 0x7 shift
-# 7
-slash 0x8 shift
-braceleft 0x8 altgr
-# 8
-parenleft 0x9 shift
-bracketleft 0x9 altgr
-# 9
-parenright 0xa shift
-bracketright 0xa altgr
-# 0
-equal 0xb shift
-braceright 0xb altgr
-
-plus 0xc
-question 0xc shift
-backslash 0xc altgr
-
-acute 0xd
-dead_acute 0xd
-grave 0xd shift
-dead_grave 0xd shift
-
-#
-# QWERTY first row
-#
-EuroSign 0x12 altgr
-aring 0x1a
-Aring 0x1a shift
-dead_diaeresis 0x1b
-dead_circumflex 0x1b shift
-dead_tilde 0x1b altgr
-
-#
-# QWERTY second row
-#
-odiaeresis 0x27
-Odiaeresis 0x27 shift
-adiaeresis 0x28
-Adiaeresis 0x28 shift
-apostrophe 0x2b
-asterisk 0x2b shift
-
-#
-# QWERTY third row
-#
-less 0x56
-greater 0x56 shift
-bar 0x56 altgr
-mu 0x32 altgr
-comma 0x33
-semicolon 0x33 shift
-period 0x34
-colon 0x34 shift
-minus 0x35
-underscore 0x35 shift
-
+++ /dev/null
-# generated from XKB map th
-include common
-map 0x41e
-exclam 0x02 shift
-Thai_lakkhangyao 0x02 altgr
-plus 0x02 shift altgr
-at 0x03 shift
-slash 0x03 altgr
-Thai_leknung 0x03 shift altgr
-numbersign 0x04 shift
-minus 0x04 altgr
-Thai_leksong 0x04 shift altgr
-dollar 0x05 shift
-Thai_phosamphao 0x05 altgr
-Thai_leksam 0x05 shift altgr
-percent 0x06 shift
-Thai_thothung 0x06 altgr
-Thai_leksi 0x06 shift altgr
-asciicircum 0x07 shift
-Thai_sarau 0x07 altgr
-Thai_sarauu 0x07 shift altgr
-ampersand 0x08 shift
-Thai_saraue 0x08 altgr
-Thai_baht 0x08 shift altgr
-asterisk 0x09 shift
-Thai_khokhwai 0x09 altgr
-Thai_lekha 0x09 shift altgr
-parenleft 0x0a shift
-Thai_totao 0x0a altgr
-Thai_lekhok 0x0a shift altgr
-parenright 0x0b shift
-Thai_chochan 0x0b altgr
-Thai_lekchet 0x0b shift altgr
-minus 0x0c
-underscore 0x0c shift
-Thai_khokhai 0x0c altgr
-Thai_lekpaet 0x0c shift altgr
-equal 0x0d
-plus 0x0d shift
-Thai_chochang 0x0d altgr
-Thai_lekkao 0x0d shift altgr
-Thai_maiyamok 0x10 altgr
-Thai_leksun 0x10 shift altgr
-Thai_saraaimaimalai 0x11 altgr
-quotedbl 0x11 shift altgr
-Thai_saraam 0x12 altgr
-Thai_dochada 0x12 shift altgr
-Thai_phophan 0x13 altgr
-Thai_thonangmontho 0x13 shift altgr
-Thai_saraa 0x14 altgr
-Thai_thothong 0x14 shift altgr
-Thai_maihanakat 0x15 altgr
-Thai_nikhahit 0x15 shift altgr
-Thai_saraii 0x16 altgr
-Thai_maitri 0x16 shift altgr
-Thai_rorua 0x17 altgr
-Thai_nonen 0x17 shift altgr
-Thai_nonu 0x18 altgr
-Thai_paiyannoi 0x18 shift altgr
-Thai_yoyak 0x19 altgr
-Thai_yoying 0x19 shift altgr
-bracketleft 0x1a
-braceleft 0x1a shift
-Thai_bobaimai 0x1a altgr
-Thai_thothan 0x1a shift altgr
-bracketright 0x1b
-braceright 0x1b shift
-Thai_loling 0x1b altgr
-comma 0x1b shift altgr
-Thai_fofan 0x1e altgr
-Thai_ru 0x1e shift altgr
-Thai_hohip 0x1f altgr
-Thai_khorakhang 0x1f shift altgr
-Thai_kokai 0x20 altgr
-Thai_topatak 0x20 shift altgr
-Thai_dodek 0x21 altgr
-Thai_sarao 0x21 shift altgr
-Thai_sarae 0x22 altgr
-Thai_chochoe 0x22 shift altgr
-Thai_maitho 0x23 altgr
-Thai_maitaikhu 0x23 shift altgr
-Thai_maiek 0x24 altgr
-Thai_maichattawa 0x24 shift altgr
-Thai_saraaa 0x25 altgr
-Thai_sorusi 0x25 shift altgr
-Thai_sosua 0x26 altgr
-Thai_sosala 0x26 shift altgr
-semicolon 0x27
-colon 0x27 shift
-Thai_wowaen 0x27 altgr
-Thai_soso 0x27 shift altgr
-apostrophe 0x28
-quotedbl 0x28 shift
-Thai_ngongu 0x28 altgr
-period 0x28 shift altgr
-grave 0x29
-asciitilde 0x29 shift
-underscore 0x29 altgr
-percent 0x29 shift altgr
-ISO_First_Group 0x2a shift
-backslash 0x2b
-bar 0x2b shift
-Thai_khokhuat 0x2b altgr
-Thai_khokhon 0x2b shift altgr
-Thai_phophung 0x2c altgr
-parenleft 0x2c shift altgr
-Thai_popla 0x2d altgr
-parenright 0x2d shift altgr
-Thai_saraae 0x2e altgr
-Thai_choching 0x2e shift altgr
-Thai_oang 0x2f altgr
-Thai_honokhuk 0x2f shift altgr
-Thai_sarai 0x30 altgr
-Thai_phinthu 0x30 shift altgr
-Thai_sarauee 0x31 altgr
-Thai_thanthakhat 0x31 shift altgr
-Thai_thothahan 0x32 altgr
-question 0x32 shift altgr
-comma 0x33
-less 0x33 shift
-Thai_moma 0x33 altgr
-Thai_thophuthao 0x33 shift altgr
-period 0x34
-greater 0x34 shift
-Thai_saraaimaimuan 0x34 altgr
-Thai_lochula 0x34 shift altgr
-slash 0x35
-question 0x35 shift
-Thai_fofa 0x35 altgr
-Thai_lu 0x35 shift altgr
-ISO_Last_Group 0x36 shift
+++ /dev/null
-# generated from XKB map tr
-include common
-map 0x41f
-exclam 0x02 shift
-onesuperior 0x02 altgr
-exclamdown 0x02 shift altgr
-apostrophe 0x03 shift
-at 0x03 altgr
-oneeighth 0x03 shift altgr
-dead_circumflex 0x04 shift
-numbersign 0x04 altgr
-sterling 0x04 shift altgr
-plus 0x05 shift
-dollar 0x05 altgr
-percent 0x06 shift
-onehalf 0x06 altgr
-threeeighths 0x06 shift altgr
-ampersand 0x07 shift
-asciicircum 0x07 altgr
-fiveeighths 0x07 shift altgr
-slash 0x08 shift
-braceleft 0x08 altgr
-seveneighths 0x08 shift altgr
-parenleft 0x09 shift
-bracketleft 0x09 altgr
-trademark 0x09 shift altgr
-parenright 0x0a shift
-bracketright 0x0a altgr
-plusminus 0x0a shift altgr
-equal 0x0b shift
-braceright 0x0b altgr
-degree 0x0b shift altgr
-asterisk 0x0c
-question 0x0c shift
-backslash 0x0c altgr
-questiondown 0x0c shift altgr
-minus 0x0d
-underscore 0x0d shift
-dead_cedilla 0x0d altgr
-dead_ogonek 0x0d shift altgr
-at 0x10 altgr
-Greek_OMEGA 0x10 shift altgr
-lstroke 0x11 altgr
-Lstroke 0x11 shift altgr
-EuroSign 0x12 altgr
-paragraph 0x13 altgr
-registered 0x13 shift altgr
-tslash 0x14 altgr
-Tslash 0x14 shift altgr
-leftarrow 0x15 altgr
-yen 0x15 shift altgr
-downarrow 0x16 altgr
-uparrow 0x16 shift altgr
-idotless 0x17
-I 0x17 shift
-rightarrow 0x17 altgr
-oslash 0x18 altgr
-Ooblique 0x18 shift altgr
-thorn 0x19 altgr
-THORN 0x19 shift altgr
-gbreve 0x1a
-Gbreve 0x1a shift
-dead_diaeresis 0x1a altgr
-dead_abovering 0x1a shift altgr
-udiaeresis 0x1b
-Udiaeresis 0x1b shift
-asciitilde 0x1b altgr
-dead_macron 0x1b shift altgr
-ae 0x1e altgr
-AE 0x1e shift altgr
-ssharp 0x1f altgr
-section 0x1f shift altgr
-eth 0x20 altgr
-ETH 0x20 shift altgr
-dstroke 0x21 altgr
-ordfeminine 0x21 shift altgr
-eng 0x22 altgr
-ENG 0x22 shift altgr
-hstroke 0x23 altgr
-Hstroke 0x23 shift altgr
-kra 0x25 altgr
-ampersand 0x25 shift altgr
-lstroke 0x26 altgr
-Lstroke 0x26 shift altgr
-scedilla 0x27
-Scedilla 0x27 shift
-dead_acute 0x27 altgr
-dead_doubleacute 0x27 shift altgr
-i 0x28
-Iabovedot 0x28 shift
-dead_circumflex 0x28 altgr
-dead_caron 0x28 shift altgr
-backslash 0x29
-quotedbl 0x29 shift
-asciitilde 0x29 altgr
-comma 0x2b
-semicolon 0x2b shift
-bar 0x2b altgr
-dead_breve 0x2b shift altgr
-guillemotleft 0x2c altgr
-less 0x2c shift altgr
-guillemotright 0x2d altgr
-greater 0x2d shift altgr
-cent 0x2e altgr
-copyright 0x2e shift altgr
-leftdoublequotemark 0x2f altgr
-grave 0x2f shift altgr
-rightdoublequotemark 0x30 altgr
-apostrophe 0x30 shift altgr
-mu 0x32 altgr
-masculine 0x32 shift altgr
-odiaeresis 0x33
-Odiaeresis 0x33 shift
-less 0x33 altgr
-multiply 0x33 shift altgr
-ccedilla 0x34
-Ccedilla 0x34 shift
-greater 0x34 altgr
-division 0x34 shift altgr
-period 0x35
-colon 0x35 shift
-dead_belowdot 0x35 altgr
-dead_abovedot 0x35 shift altgr
+++ /dev/null
-/*
- * qemu user main
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <string.h>
-#include <errno.h>
-#include <unistd.h>
-
-#include "qemu.h"
-
-#define DEBUG_LOGFILE "/tmp/qemu.log"
-
-#ifdef __APPLE__
-#include <crt_externs.h>
-# define environ (*_NSGetEnviron())
-#endif
-
-static const char *interp_prefix = CONFIG_QEMU_PREFIX;
-
-#if defined(__i386__) && !defined(CONFIG_STATIC)
-/* Force usage of an ELF interpreter even if it is an ELF shared
- object ! */
-const char interp[] __attribute__((section(".interp"))) = "/lib/ld-linux.so.2";
-#endif
-
-/* for recent libc, we add these dummy symbols which are not declared
- when generating a linked object (bug in ld ?) */
-#if (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 3)) && !defined(CONFIG_STATIC)
-long __preinit_array_start[0];
-long __preinit_array_end[0];
-long __init_array_start[0];
-long __init_array_end[0];
-long __fini_array_start[0];
-long __fini_array_end[0];
-#endif
-
-/* XXX: on x86 MAP_GROWSDOWN only works if ESP <= address + 32, so
- we allocate a bigger stack. Need a better solution, for example
- by remapping the process stack directly at the right place */
-unsigned long x86_stack_size = 512 * 1024;
-
-void gemu_log(const char *fmt, ...)
-{
- va_list ap;
-
- va_start(ap, fmt);
- vfprintf(stderr, fmt, ap);
- va_end(ap);
-}
-/* timers for rdtsc */
-
-#if defined(__i386__)
-
-int64_t cpu_get_real_ticks(void)
-{
- int64_t val;
- asm volatile ("rdtsc" : "=A" (val));
- return val;
-}
-
-#elif defined(__x86_64__)
-
-int64_t cpu_get_real_ticks(void)
-{
- uint32_t low,high;
- int64_t val;
- asm volatile("rdtsc" : "=a" (low), "=d" (high));
- val = high;
- val <<= 32;
- val |= low;
- return val;
-}
-
-#else
-
-static uint64_t emu_time;
-
-int64_t cpu_get_real_ticks(void)
-{
- return emu_time++;
-}
-
-#endif
-
-#ifdef TARGET_I386
-/***********************************************************/
-/* CPUX86 core interface */
-
-uint64_t cpu_get_tsc(CPUX86State *env)
-{
- return cpu_get_real_ticks();
-}
-
-void cpu_loop()
-{
-}
-#endif
-
-void usage(void)
-{
- printf("qemu-" TARGET_ARCH " version " QEMU_VERSION ", Copyright (c) 2003-2004 Fabrice Bellard\n"
- "usage: qemu-" TARGET_ARCH " [-h] [-d opts] [-L path] [-s size] program [arguments...]\n"
- "Linux CPU emulator (compiled for %s emulation)\n"
- "\n"
- "-h print this help\n"
- "-L path set the elf interpreter prefix (default=%s)\n"
- "-s size set the stack size in bytes (default=%ld)\n"
- "\n"
- "debug options:\n"
-#ifdef USE_CODE_COPY
- "-no-code-copy disable code copy acceleration\n"
-#endif
- "-l options activate log (logfile=%s)\n"
- "-p xen port number\n",
- "-d xen domain id\n",
- TARGET_ARCH,
- interp_prefix,
- x86_stack_size,
- DEBUG_LOGFILE);
- _exit(1);
-}
-
-/* XXX: currently only used for async signals (see signal.c) */
-CPUState *global_env;
-/* used only if single thread */
-CPUState *cpu_single_env = NULL;
-
-/* used to free thread contexts */
-TaskState *first_task_state;
-
-int main(int argc, char **argv)
-{
- const char *filename;
- struct target_pt_regs regs1, *regs = ®s1;
- struct image_info info1, *info = &info1;
- TaskState ts1, *ts = &ts1;
- CPUState *env;
- int optind;
- const char *r;
-
- if (argc <= 1)
- usage();
-
- /* init debug */
- cpu_set_log_filename(DEBUG_LOGFILE);
- cpu_set_log(0);
-
- optind = 1;
- for(;;) {
- if (optind >= argc)
- break;
- r = argv[optind];
- if (r[0] != '-')
- break;
- optind++;
- r++;
- if (!strcmp(r, "-")) {
- break;
- } else if (!strcmp(r, "l")) {
- int mask;
- CPULogItem *item;
-
- if (optind >= argc)
- break;
-
- r = argv[optind++];
- mask = cpu_str_to_log_mask(r);
- if (!mask) {
- printf("Log items (comma separated):\n");
- for(item = cpu_log_items; item->mask != 0; item++) {
- printf("%-10s %s\n", item->name, item->help);
- }
- exit(1);
- }
- cpu_set_log(mask);
- } else if (!strcmp(r, "s")) {
- r = argv[optind++];
- x86_stack_size = strtol(r, (char **)&r, 0);
- if (x86_stack_size <= 0)
- usage();
- if (*r == 'M')
- x86_stack_size *= 1024 * 1024;
- else if (*r == 'k' || *r == 'K')
- x86_stack_size *= 1024;
- } else if (!strcmp(r, "L")) {
- interp_prefix = argv[optind++];
- } else if (!strcmp(r, "p")) {
- qemu_host_page_size = atoi(argv[optind++]);
- if (qemu_host_page_size == 0 ||
- (qemu_host_page_size & (qemu_host_page_size - 1)) != 0) {
- fprintf(stderr, "page size must be a power of two\n");
- exit(1);
- }
- } else
-#ifdef USE_CODE_COPY
- if (!strcmp(r, "no-code-copy")) {
- code_copy_enabled = 0;
- } else
-#endif
- {
- usage();
- }
- }
- if (optind >= argc)
- usage();
- filename = argv[optind];
-
- /* Zero out regs */
- memset(regs, 0, sizeof(struct target_pt_regs));
-
- /* Zero out image_info */
- memset(info, 0, sizeof(struct image_info));
-
- /* Scan interp_prefix dir for replacement files. */
- init_paths(interp_prefix);
-
- /* NOTE: we need to init the CPU at this stage to get
- qemu_host_page_size */
- env = cpu_init();
-
- global_env = env;
-
- /* build Task State */
- memset(ts, 0, sizeof(TaskState));
- env->opaque = ts;
- ts->used = 1;
- env->user_mode_only = 1;
-
- cpu_loop(env);
- /* never exits */
- return 0;
-}
+++ /dev/null
-/*
- * QEMU monitor
- *
- * Copyright (c) 2003-2004 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "vl.h"
-#include <dirent.h>
-
-//#define DEBUG
-//#define DEBUG_COMPLETION
-
-#ifndef offsetof
-#define offsetof(type, field) ((size_t) &((type *)0)->field)
-#endif
-
-/*
- * Supported types:
- *
- * 'F' filename
- * 'B' block device name
- * 's' string (accept optional quote)
- * 'i' integer
- * '/' optional gdb-like print format (like "/10x")
- *
- * '?' optional type (for 'F', 's' and 'i')
- *
- */
-
-typedef struct term_cmd_t {
- const char *name;
- const char *args_type;
- void (*handler)();
- const char *params;
- const char *help;
-} term_cmd_t;
-
-static CharDriverState *monitor_hd;
-
-static term_cmd_t term_cmds[];
-static term_cmd_t info_cmds[];
-
-static char term_outbuf[1024];
-static int term_outbuf_index;
-
-static void monitor_start_input(void);
-
-void term_flush(void)
-{
- if (term_outbuf_index > 0) {
- if(monitor_hd)
- qemu_chr_write(monitor_hd, term_outbuf, term_outbuf_index);
- else
- fwrite(term_outbuf, term_outbuf_index, 1, stderr);
- term_outbuf_index = 0;
- }
-}
-
-/* flush at every end of line or if the buffer is full */
-void term_puts(const char *str)
-{
- int c;
- for(;;) {
- c = *str++;
- if (c == '\0')
- break;
- term_outbuf[term_outbuf_index++] = c;
- if (term_outbuf_index >= sizeof(term_outbuf) ||
- c == '\n')
- term_flush();
- }
-}
-
-void term_vprintf(const char *fmt, va_list ap)
-{
- char buf[4096];
- vsnprintf(buf, sizeof(buf), fmt, ap);
- term_puts(buf);
-}
-
-void term_printf(const char *fmt, ...)
-{
- va_list ap;
- va_start(ap, fmt);
- term_vprintf(fmt, ap);
- va_end(ap);
-}
-
-static int compare_cmd(const char *name, const char *list)
-{
- const char *p, *pstart;
- int len;
- len = strlen(name);
- p = list;
- for(;;) {
- pstart = p;
- p = strchr(p, '|');
- if (!p)
- p = pstart + strlen(pstart);
- if ((p - pstart) == len && !memcmp(pstart, name, len))
- return 1;
- if (*p == '\0')
- break;
- p++;
- }
- return 0;
-}
-
-static void help_cmd1(term_cmd_t *cmds, const char *prefix, const char *name)
-{
- term_cmd_t *cmd;
-
- for(cmd = cmds; cmd->name != NULL; cmd++) {
- if (!name || !strcmp(name, cmd->name))
- term_printf("%s%s %s -- %s\n", prefix, cmd->name, cmd->params, cmd->help);
- }
-}
-
-static void help_cmd(const char *name)
-{
- if (name && !strcmp(name, "info")) {
- help_cmd1(info_cmds, "info ", NULL);
- } else {
- help_cmd1(term_cmds, "", name);
- if (name && !strcmp(name, "log")) {
- CPULogItem *item;
- term_printf("Log items (comma separated):\n");
- term_printf("%-10s %s\n", "none", "remove all logs");
- for(item = cpu_log_items; item->mask != 0; item++) {
- term_printf("%-10s %s\n", item->name, item->help);
- }
- }
- }
-}
-
-static void do_help(const char *name)
-{
- help_cmd(name);
-}
-
-static void do_commit(void)
-{
- int i;
-
- for (i = 0; i < MAX_DISKS; i++) {
- if (bs_table[i]) {
- bdrv_commit(bs_table[i]);
- }
- }
-}
-
-static void do_info(const char *item)
-{
- term_cmd_t *cmd;
-
- if (!item)
- goto help;
- for(cmd = info_cmds; cmd->name != NULL; cmd++) {
- if (compare_cmd(item, cmd->name))
- goto found;
- }
- help:
- help_cmd("info");
- return;
- found:
- cmd->handler();
-}
-
-static void do_info_version(void)
-{
- term_printf("%s\n", QEMU_VERSION);
-}
-
-static void do_info_network(void)
-{
- int i, j;
- NetDriverState *nd;
-
- for(i = 0; i < nb_nics; i++) {
- nd = &nd_table[i];
- term_printf("%d: ifname=%s macaddr=", i, nd->ifname);
- for(j = 0; j < 6; j++) {
- if (j > 0)
- term_printf(":");
- term_printf("%02x", nd->macaddr[j]);
- }
- term_printf("\n");
- }
-}
-
-static void do_info_block(void)
-{
- bdrv_info();
-}
-
-static void do_info_history (void)
-{
- int i;
- const char *str;
-
- i = 0;
- for(;;) {
- str = readline_get_history(i);
- if (!str)
- break;
- term_printf("%d: '%s'\n", i, str);
- i++;
- }
-}
-
-extern void destroy_hvm_domain(void);
-static void do_quit(void)
-{
- destroy_hvm_domain();
- exit(0);
-}
-
-typedef struct {
- int keycode;
- const char *name;
-} KeyDef;
-
-static const KeyDef key_defs[] = {
- { 0x2a, "shift" },
- { 0x36, "shift_r" },
-
- { 0x38, "alt" },
- { 0xb8, "alt_r" },
- { 0x1d, "ctrl" },
- { 0x9d, "ctrl_r" },
-
- { 0xdd, "menu" },
-
- { 0x01, "esc" },
-
- { 0x02, "1" },
- { 0x03, "2" },
- { 0x04, "3" },
- { 0x05, "4" },
- { 0x06, "5" },
- { 0x07, "6" },
- { 0x08, "7" },
- { 0x09, "8" },
- { 0x0a, "9" },
- { 0x0b, "0" },
- { 0x0e, "backspace" },
-
- { 0x0f, "tab" },
- { 0x10, "q" },
- { 0x11, "w" },
- { 0x12, "e" },
- { 0x13, "r" },
- { 0x14, "t" },
- { 0x15, "y" },
- { 0x16, "u" },
- { 0x17, "i" },
- { 0x18, "o" },
- { 0x19, "p" },
-
- { 0x1c, "ret" },
-
- { 0x1e, "a" },
- { 0x1f, "s" },
- { 0x20, "d" },
- { 0x21, "f" },
- { 0x22, "g" },
- { 0x23, "h" },
- { 0x24, "j" },
- { 0x25, "k" },
- { 0x26, "l" },
-
- { 0x2c, "z" },
- { 0x2d, "x" },
- { 0x2e, "c" },
- { 0x2f, "v" },
- { 0x30, "b" },
- { 0x31, "n" },
- { 0x32, "m" },
-
- { 0x39, "spc" },
- { 0x3a, "caps_lock" },
- { 0x3b, "f1" },
- { 0x3c, "f2" },
- { 0x3d, "f3" },
- { 0x3e, "f4" },
- { 0x3f, "f5" },
- { 0x40, "f6" },
- { 0x41, "f7" },
- { 0x42, "f8" },
- { 0x43, "f9" },
- { 0x44, "f10" },
- { 0x45, "num_lock" },
- { 0x46, "scroll_lock" },
-
- { 0x56, "<" },
-
- { 0x57, "f11" },
- { 0x58, "f12" },
-
- { 0xb7, "print" },
-
- { 0xc7, "home" },
- { 0xc9, "pgup" },
- { 0xd1, "pgdn" },
- { 0xcf, "end" },
-
- { 0xcb, "left" },
- { 0xc8, "up" },
- { 0xd0, "down" },
- { 0xcd, "right" },
-
- { 0xd2, "insert" },
- { 0xd3, "delete" },
- { 0, NULL },
-};
-
-static int get_keycode(const char *key)
-{
- const KeyDef *p;
-
- for(p = key_defs; p->name != NULL; p++) {
- if (!strcmp(key, p->name))
- return p->keycode;
- }
- return -1;
-}
-
-static void do_send_key(const char *string)
-{
- char keybuf[16], *q;
- uint8_t keycodes[16];
- const char *p;
- int nb_keycodes, keycode, i;
-
- nb_keycodes = 0;
- p = string;
- while (*p != '\0') {
- q = keybuf;
- while (*p != '\0' && *p != '-') {
- if ((q - keybuf) < sizeof(keybuf) - 1) {
- *q++ = *p;
- }
- p++;
- }
- *q = '\0';
- keycode = get_keycode(keybuf);
- if (keycode < 0) {
- term_printf("unknown key: '%s'\n", keybuf);
- return;
- }
- keycodes[nb_keycodes++] = keycode;
- if (*p == '\0')
- break;
- p++;
- }
- /* key down events */
- for(i = 0; i < nb_keycodes; i++) {
- keycode = keycodes[i];
- if (keycode & 0x80)
- kbd_put_keycode(0xe0);
- kbd_put_keycode(keycode & 0x7f);
- }
- /* key up events */
- for(i = nb_keycodes - 1; i >= 0; i--) {
- keycode = keycodes[i];
- if (keycode & 0x80)
- kbd_put_keycode(0xe0);
- kbd_put_keycode(keycode | 0x80);
- }
-}
-
-
-static int eject_device(BlockDriverState *bs, int force)
-{
- if (bdrv_is_inserted(bs)) {
- if (!force) {
- if (!bdrv_is_removable(bs)) {
- term_printf("device is not removable\n");
- return -1;
- }
- if (bdrv_is_locked(bs)) {
- term_printf("device is locked\n");
- return -1;
- }
- }
- bdrv_close(bs);
- }
- return 0;
-}
-
-static void do_eject(int force, const char *filename)
-{
- char cmd[1024];
- BlockDriverState *bs;
-
- bs = bdrv_find(filename);
- if (!bs) {
- term_printf("device not found\n");
- return;
- }
- eject_device(bs, force);
- sprintf(cmd, "eject %s", filename);
- system(cmd);
-
-}
-
-static void do_change(const char *device, const char *filename)
-{
- BlockDriverState *bs;
-#if 0
- int i;
- char password[256];
-#endif
-
- bs = bdrv_find(device);
- if (!bs) {
- term_printf("device not found\n");
- return;
- }
- if (eject_device(bs, 0) < 0)
- return;
- bdrv_open(bs, filename, 0);
-#if 0
- if (bdrv_is_encrypted(bs)) {
- term_printf("%s is encrypted.\n", device);
- for(i = 0; i < 3; i++) {
- monitor_readline("Password: ", 1, password, sizeof(password));
- if (bdrv_set_key(bs, password) == 0)
- break;
- term_printf("invalid password\n");
- }
- }
-#endif
-}
-
-static void do_screen_dump(const char *filename)
-{
- vga_screen_dump(filename);
-}
-
-static void do_log(const char *items)
-{
- int mask;
-
- if (!strcmp(items, "none")) {
- mask = 0;
- } else {
- mask = cpu_str_to_log_mask(items);
- if (!mask) {
- help_cmd("log");
- return;
- }
- }
- cpu_set_log(mask);
-}
-
-static term_cmd_t term_cmds[] = {
- { "help|?", "s?", do_help,
- "[cmd]", "show the help" },
- { "commit", "", do_commit,
- "", "commit changes to the disk images (if -snapshot is used)" },
- { "info", "s?", do_info,
- "subcommand", "show various information about the system state" },
- { "q|quit", "", do_quit,
- "", "quit the emulator" },
- { "eject", "-fB", do_eject,
- "[-f] device", "eject a removable media (use -f to force it)" },
- { "change", "BF", do_change,
- "device filename", "change a removable media" },
- { "screendump", "F", do_screen_dump,
- "filename", "save screen into PPM image 'filename'" },
- { "log", "s", do_log,
- "item1[,...]", "activate logging of the specified items to '/tmp/qemu.log'" },
- { "q|quit", "", do_quit,
- "", "quit the emulator" },
- { "sendkey", "s", do_send_key,
- "keys", "send keys to the VM (e.g. 'sendkey ctrl-alt-f1')" },
- { "usb_add", "s", do_usb_add,
- "device", "add USB device (e.g. 'host:bus.addr' or 'host:vendor_id:product_id')" },
- { "usb_del", "s", do_usb_del,
- "device", "remove USB device 'bus.addr'" },
- { NULL, NULL, },
-};
-
-static term_cmd_t info_cmds[] = {
- { "version", "", do_info_version,
- "", "show the version of qemu" },
- { "network", "", do_info_network,
- "", "show the network state" },
- { "block", "", do_info_block,
- "", "show the block devices" },
- { "history", "", do_info_history,
- "", "show the command line history", },
- { "irq", "", irq_info,
- "", "show the interrupts statistics (if available)", },
- { "pic", "", pic_info,
- "", "show i8259 (PIC) state", },
- { "pci", "", pci_info,
- "", "show PCI info", },
- { "usb", "", usb_info,
- "", "show guest USB devices", },
- { "usbhost", "", usb_host_info,
- "", "show host USB devices", },
- { "hvmiopage", "", sp_info,
- "", "show HVM device model shared page info", },
- { NULL, NULL, },
-};
-
-static int get_str(char *buf, int buf_size, const char **pp)
-{
- const char *p;
- char *q;
- int c;
-
- q = buf;
- p = *pp;
- while (isspace(*p))
- p++;
- if (*p == '\0') {
- fail:
- *q = '\0';
- *pp = p;
- return -1;
- }
- if (*p == '\"') {
- p++;
- while (*p != '\0' && *p != '\"') {
- if (*p == '\\') {
- p++;
- c = *p++;
- switch(c) {
- case 'n':
- c = '\n';
- break;
- case 'r':
- c = '\r';
- break;
- case '\\':
- case '\'':
- case '\"':
- break;
- default:
- qemu_printf("unsupported escape code: '\\%c'\n", c);
- goto fail;
- }
- if ((q - buf) < buf_size - 1) {
- *q++ = c;
- }
- } else {
- if ((q - buf) < buf_size - 1) {
- *q++ = *p;
- }
- p++;
- }
- }
- if (*p != '\"') {
- qemu_printf("unterminated string\n");
- goto fail;
- }
- p++;
- } else {
- while (*p != '\0' && !isspace(*p)) {
- if ((q - buf) < buf_size - 1) {
- *q++ = *p;
- }
- p++;
- }
- }
- *q = '\0';
- *pp = p;
- return 0;
-}
-
-#define MAX_ARGS 16
-
-static void monitor_handle_command(const char *cmdline)
-{
- const char *p, *pstart, *typestr;
- char *q;
- int c, nb_args, len, i;
- term_cmd_t *cmd;
- char cmdname[256];
- char buf[1024];
- void *str_allocated[MAX_ARGS];
- void *args[MAX_ARGS];
-
-#ifdef DEBUG
- term_printf("command='%s'\n", cmdline);
-#endif
-
- /* extract the command name */
- p = cmdline;
- q = cmdname;
- while (isspace(*p))
- p++;
- if (*p == '\0')
- return;
- pstart = p;
- while (*p != '\0' && *p != '/' && !isspace(*p))
- p++;
- len = p - pstart;
- if (len > sizeof(cmdname) - 1)
- len = sizeof(cmdname) - 1;
- memcpy(cmdname, pstart, len);
- cmdname[len] = '\0';
-
- /* find the command */
- for(cmd = term_cmds; cmd->name != NULL; cmd++) {
- if (compare_cmd(cmdname, cmd->name))
- goto found;
- }
- term_printf("unknown command: '%s'\n", cmdname);
- return;
- found:
-
- for(i = 0; i < MAX_ARGS; i++)
- str_allocated[i] = NULL;
-
- /* parse the parameters */
- typestr = cmd->args_type;
- nb_args = 0;
- for(;;) {
- c = *typestr;
- if (c == '\0')
- break;
- typestr++;
- switch(c) {
- case 'F':
- case 'B':
- case 's':
- {
- int ret;
- char *str;
-
- while (isspace(*p))
- p++;
- if (*typestr == '?') {
- typestr++;
- if (*p == '\0') {
- /* no optional string: NULL argument */
- str = NULL;
- goto add_str;
- }
- }
- ret = get_str(buf, sizeof(buf), &p);
- if (ret < 0) {
- switch(c) {
- case 'F':
- term_printf("%s: filename expected\n", cmdname);
- break;
- case 'B':
- term_printf("%s: block device name expected\n", cmdname);
- break;
- default:
- term_printf("%s: string expected\n", cmdname);
- break;
- }
- goto fail;
- }
- str = qemu_malloc(strlen(buf) + 1);
- strcpy(str, buf);
- str_allocated[nb_args] = str;
- add_str:
- if (nb_args >= MAX_ARGS) {
- error_args:
- term_printf("%s: too many arguments\n", cmdname);
- goto fail;
- }
- args[nb_args++] = str;
- }
- break;
- case '-':
- {
- long has_option;
- /* option */
-
- c = *typestr++;
- if (c == '\0')
- goto bad_type;
- while (isspace(*p))
- p++;
- has_option = 0;
- if (*p == '-') {
- p++;
- if (*p != c) {
- term_printf("%s: unsupported option -%c\n",
- cmdname, *p);
- goto fail;
- }
- p++;
- has_option = 1;
- }
- if (nb_args >= MAX_ARGS)
- goto error_args;
- args[nb_args++] = (void *)has_option;
- }
- break;
- /* TODO: add more commands we need here to support hvm device model */
- case '/':
- case 'i':
- default:
- bad_type:
- term_printf("%s: unknown type '%c',not support now.\n", cmdname, c);
- goto fail;
- }
- }
- /* check that all arguments were parsed */
- while (isspace(*p))
- p++;
- if (*p != '\0') {
- term_printf("%s: extraneous characters at the end of line\n",
- cmdname);
- goto fail;
- }
-
- switch(nb_args) {
- case 0:
- cmd->handler();
- break;
- case 1:
- cmd->handler(args[0]);
- break;
- case 2:
- cmd->handler(args[0], args[1]);
- break;
- case 3:
- cmd->handler(args[0], args[1], args[2]);
- break;
- case 4:
- cmd->handler(args[0], args[1], args[2], args[3]);
- break;
- case 5:
- cmd->handler(args[0], args[1], args[2], args[3], args[4]);
- break;
- case 6:
- cmd->handler(args[0], args[1], args[2], args[3], args[4], args[5]);
- break;
- default:
- term_printf("unsupported number of arguments: %d\n", nb_args);
- goto fail;
- }
- fail:
- for(i = 0; i < MAX_ARGS; i++)
- qemu_free(str_allocated[i]);
- return;
-}
-
-static int term_can_read(void *opaque)
-{
- return 128;
-}
-
-static void term_read(void *opaque, const uint8_t *buf, int size)
-{
- int i;
- for(i = 0; i < size; i++)
- readline_handle_byte(buf[i]);
-}
-
-static void monitor_start_input(void);
-
-static void monitor_handle_command1(void *opaque, const char *cmdline)
-{
- monitor_handle_command(cmdline);
- monitor_start_input();
-}
-
-static void monitor_start_input(void)
-{
- readline_start("(HVMXen) ", 0, monitor_handle_command1, NULL);
-}
-
-void monitor_init(CharDriverState *hd, int show_banner)
-{
- monitor_hd = hd;
- if (show_banner) {
- term_printf("HVM device model. type 'q' to exit\n");
- }
- qemu_chr_add_read_handler(hd, term_can_read, term_read, NULL);
- monitor_start_input();
-}
+++ /dev/null
-/*
- * QEMU low level functions
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <string.h>
-#include <errno.h>
-#include <unistd.h>
-
-#include "cpu.h"
-
-#if defined(__i386__) && !defined(CONFIG_SOFTMMU) && !defined(CONFIG_USER_ONLY)
-
-#include <sys/mman.h>
-#include <sys/ipc.h>
-
-/* When not using soft mmu, libc independant functions are needed for
- the CPU core because it needs to use alternates stacks and
- libc/thread incompatibles settings */
-
-#include <linux/unistd.h>
-
-#define QEMU_SYSCALL0(name) \
-{ \
-long __res; \
-__asm__ volatile ("int $0x80" \
- : "=a" (__res) \
- : "0" (__NR_##name)); \
-return __res; \
-}
-
-#define QEMU_SYSCALL1(name,arg1) \
-{ \
-long __res; \
-__asm__ volatile ("int $0x80" \
- : "=a" (__res) \
- : "0" (__NR_##name),"b" ((long)(arg1))); \
-return __res; \
-}
-
-#define QEMU_SYSCALL2(name,arg1,arg2) \
-{ \
-long __res; \
-__asm__ volatile ("int $0x80" \
- : "=a" (__res) \
- : "0" (__NR_##name),"b" ((long)(arg1)),"c" ((long)(arg2))); \
-return __res; \
-}
-
-#define QEMU_SYSCALL3(name,arg1,arg2,arg3) \
-{ \
-long __res; \
-__asm__ volatile ("int $0x80" \
- : "=a" (__res) \
- : "0" (__NR_##name),"b" ((long)(arg1)),"c" ((long)(arg2)), \
- "d" ((long)(arg3))); \
-return __res; \
-}
-
-#define QEMU_SYSCALL4(name,arg1,arg2,arg3,arg4) \
-{ \
-long __res; \
-__asm__ volatile ("int $0x80" \
- : "=a" (__res) \
- : "0" (__NR_##name),"b" ((long)(arg1)),"c" ((long)(arg2)), \
- "d" ((long)(arg3)),"S" ((long)(arg4))); \
-return __res; \
-}
-
-#define QEMU_SYSCALL5(name,arg1,arg2,arg3,arg4,arg5) \
-{ \
-long __res; \
-__asm__ volatile ("int $0x80" \
- : "=a" (__res) \
- : "0" (__NR_##name),"b" ((long)(arg1)),"c" ((long)(arg2)), \
- "d" ((long)(arg3)),"S" ((long)(arg4)),"D" ((long)(arg5))); \
-return __res; \
-}
-
-#define QEMU_SYSCALL6(name,arg1,arg2,arg3,arg4,arg5,arg6) \
-{ \
-long __res; \
-__asm__ volatile ("push %%ebp ; movl %%eax,%%ebp ; movl %1,%%eax ; int $0x80 ; pop %%ebp" \
- : "=a" (__res) \
- : "i" (__NR_##name),"b" ((long)(arg1)),"c" ((long)(arg2)), \
- "d" ((long)(arg3)),"S" ((long)(arg4)),"D" ((long)(arg5)), \
- "0" ((long)(arg6))); \
-return __res; \
-}
-
-int qemu_write(int fd, const void *buf, size_t n)
-{
- QEMU_SYSCALL3(write, fd, buf, n);
-}
-
-
-
-/****************************************************************/
-/* shmat replacement */
-
-int qemu_ipc(int call, unsigned long first,
- unsigned long second, unsigned long third,
- void *ptr, unsigned long fifth)
-{
- QEMU_SYSCALL6(ipc, call, first, second, third, ptr, fifth);
-}
-
-#define SHMAT 21
-
-/* we must define shmat so that a specific address will be used when
- mapping the X11 ximage */
-void *shmat(int shmid, const void *shmaddr, int shmflg)
-{
- void *ptr;
- int ret;
- /* we give an address in the right memory area */
- if (!shmaddr)
- shmaddr = get_mmap_addr(8192 * 1024);
- ret = qemu_ipc(SHMAT, shmid, shmflg, (unsigned long)&ptr, (void *)shmaddr, 0);
- if (ret < 0)
- return NULL;
- return ptr;
-}
-
-/****************************************************************/
-/* sigaction bypassing the threads */
-
-static int kernel_sigaction(int signum, const struct qemu_sigaction *act,
- struct qemu_sigaction *oldact,
- int sigsetsize)
-{
- QEMU_SYSCALL4(rt_sigaction, signum, act, oldact, sigsetsize);
-}
-
-int qemu_sigaction(int signum, const struct qemu_sigaction *act,
- struct qemu_sigaction *oldact)
-{
- return kernel_sigaction(signum, act, oldact, 8);
-}
-
-/****************************************************************/
-/* memory allocation */
-
-//#define DEBUG_MALLOC
-
-#define MALLOC_BASE 0xab000000
-#define PHYS_RAM_BASE 0xac000000
-
-#define MALLOC_ALIGN 16
-#define BLOCK_HEADER_SIZE 16
-
-typedef struct MemoryBlock {
- struct MemoryBlock *next;
- unsigned long size; /* size of block, including header */
-} MemoryBlock;
-
-static MemoryBlock *first_free_block;
-static unsigned long malloc_addr = MALLOC_BASE;
-
-static void *malloc_get_space(size_t size)
-{
- void *ptr;
- size = TARGET_PAGE_ALIGN(size);
- ptr = mmap((void *)malloc_addr, size,
- PROT_WRITE | PROT_READ,
- MAP_PRIVATE | MAP_FIXED | MAP_ANON, -1, 0);
- if (ptr == MAP_FAILED)
- return NULL;
- malloc_addr += size;
- return ptr;
-}
-
-void *qemu_malloc(size_t size)
-{
- MemoryBlock *mb, *mb1, **pmb;
- void *ptr;
- size_t size1, area_size;
-
- if (size == 0)
- return NULL;
-
- size = (size + BLOCK_HEADER_SIZE + MALLOC_ALIGN - 1) & ~(MALLOC_ALIGN - 1);
- pmb = &first_free_block;
- for(;;) {
- mb = *pmb;
- if (mb == NULL)
- break;
- if (size <= mb->size)
- goto found;
- pmb = &mb->next;
- }
- /* no big enough blocks found: get new space */
- area_size = TARGET_PAGE_ALIGN(size);
- mb = malloc_get_space(area_size);
- if (!mb)
- return NULL;
- size1 = area_size - size;
- if (size1 > 0) {
- /* create a new free block */
- mb1 = (MemoryBlock *)((uint8_t *)mb + size);
- mb1->next = NULL;
- mb1->size = size1;
- *pmb = mb1;
- }
- goto the_end;
- found:
- /* a free block was found: use it */
- size1 = mb->size - size;
- if (size1 > 0) {
- /* create a new free block */
- mb1 = (MemoryBlock *)((uint8_t *)mb + size);
- mb1->next = mb->next;
- mb1->size = size1;
- *pmb = mb1;
- } else {
- /* suppress the first block */
- *pmb = mb->next;
- }
- the_end:
- mb->size = size;
- mb->next = NULL;
- ptr = ((uint8_t *)mb + BLOCK_HEADER_SIZE);
-#ifdef DEBUG_MALLOC
- qemu_printf("malloc: size=0x%x ptr=0x%lx\n", size, (unsigned long)ptr);
-#endif
- return ptr;
-}
-
-void qemu_free(void *ptr)
-{
- MemoryBlock *mb;
-
- if (!ptr)
- return;
- mb = (MemoryBlock *)((uint8_t *)ptr - BLOCK_HEADER_SIZE);
- mb->next = first_free_block;
- first_free_block = mb;
-}
-
-/****************************************************************/
-/* virtual memory allocation */
-
-unsigned long mmap_addr = PHYS_RAM_BASE;
-
-void *get_mmap_addr(unsigned long size)
-{
- unsigned long addr;
- addr = mmap_addr;
- mmap_addr += ((size + 4095) & ~4095) + 4096;
- return (void *)addr;
-}
-
-#else
-
-int qemu_write(int fd, const void *buf, size_t n)
-{
- int ret;
- ret = write(fd, buf, n);
- if (ret < 0)
- return -errno;
- else
- return ret;
-}
-
-void *get_mmap_addr(unsigned long size)
-{
- return NULL;
-}
-
-void qemu_free(void *ptr)
-{
- free(ptr);
-}
-
-void *qemu_malloc(size_t size)
-{
- return malloc(size);
-}
-
-#endif
-
-void *qemu_mallocz(size_t size)
-{
- void *ptr;
- ptr = qemu_malloc(size);
- if (!ptr)
- return NULL;
- memset(ptr, 0, size);
- return ptr;
-}
-
-char *qemu_strdup(const char *str)
-{
- char *ptr;
- ptr = qemu_malloc(strlen(str) + 1);
- if (!ptr)
- return NULL;
- strcpy(ptr, str);
- return ptr;
-}
-
-/****************************************************************/
-/* printf support */
-
-static inline int qemu_isdigit(int c)
-{
- return c >= '0' && c <= '9';
-}
-
-#define OUTCHAR(c) (buflen > 0? (--buflen, *buf++ = (c)): 0)
-
-/* from BSD ppp sources */
-int qemu_vsnprintf(char *buf, int buflen, const char *fmt, va_list args)
-{
- int c, i, n;
- int width, prec, fillch;
- int base, len, neg;
- unsigned long val = 0;
- const char *f;
- char *str, *buf0;
- char num[32];
- static const char hexchars[] = "0123456789abcdef";
-
- buf0 = buf;
- --buflen;
- while (buflen > 0) {
- for (f = fmt; *f != '%' && *f != 0; ++f)
- ;
- if (f > fmt) {
- len = f - fmt;
- if (len > buflen)
- len = buflen;
- memcpy(buf, fmt, len);
- buf += len;
- buflen -= len;
- fmt = f;
- }
- if (*fmt == 0)
- break;
- c = *++fmt;
- width = prec = 0;
- fillch = ' ';
- if (c == '0') {
- fillch = '0';
- c = *++fmt;
- }
- if (c == '*') {
- width = va_arg(args, int);
- c = *++fmt;
- } else {
- while (qemu_isdigit(c)) {
- width = width * 10 + c - '0';
- c = *++fmt;
- }
- }
- if (c == '.') {
- c = *++fmt;
- if (c == '*') {
- prec = va_arg(args, int);
- c = *++fmt;
- } else {
- while (qemu_isdigit(c)) {
- prec = prec * 10 + c - '0';
- c = *++fmt;
- }
- }
- }
- /* modifiers */
- switch(c) {
- case 'l':
- c = *++fmt;
- break;
- default:
- break;
- }
- str = 0;
- base = 0;
- neg = 0;
- ++fmt;
- switch (c) {
- case 'd':
- i = va_arg(args, int);
- if (i < 0) {
- neg = 1;
- val = -i;
- } else
- val = i;
- base = 10;
- break;
- case 'o':
- val = va_arg(args, unsigned int);
- base = 8;
- break;
- case 'x':
- case 'X':
- val = va_arg(args, unsigned int);
- base = 16;
- break;
- case 'p':
- val = (unsigned long) va_arg(args, void *);
- base = 16;
- neg = 2;
- break;
- case 's':
- str = va_arg(args, char *);
- break;
- case 'c':
- num[0] = va_arg(args, int);
- num[1] = 0;
- str = num;
- break;
- default:
- *buf++ = '%';
- if (c != '%')
- --fmt; /* so %z outputs %z etc. */
- --buflen;
- continue;
- }
- if (base != 0) {
- str = num + sizeof(num);
- *--str = 0;
- while (str > num + neg) {
- *--str = hexchars[val % base];
- val = val / base;
- if (--prec <= 0 && val == 0)
- break;
- }
- switch (neg) {
- case 1:
- *--str = '-';
- break;
- case 2:
- *--str = 'x';
- *--str = '0';
- break;
- }
- len = num + sizeof(num) - 1 - str;
- } else {
- len = strlen(str);
- if (prec > 0 && len > prec)
- len = prec;
- }
- if (width > 0) {
- if (width > buflen)
- width = buflen;
- if ((n = width - len) > 0) {
- buflen -= n;
- for (; n > 0; --n)
- *buf++ = fillch;
- }
- }
- if (len > buflen)
- len = buflen;
- memcpy(buf, str, len);
- buf += len;
- buflen -= len;
- }
- *buf = 0;
- return buf - buf0;
-}
-
-void qemu_vprintf(const char *fmt, va_list ap)
-{
- char buf[1024];
- int len;
-
- len = qemu_vsnprintf(buf, sizeof(buf), fmt, ap);
- qemu_write(1, buf, len);
-}
-
-void qemu_printf(const char *fmt, ...)
-{
- va_list ap;
- va_start(ap, fmt);
- qemu_vprintf(fmt, ap);
- va_end(ap);
-}
-
+++ /dev/null
-#ifndef QEMU_OSDEP_H
-#define QEMU_OSDEP_H
-
-#include <stdarg.h>
-
-int qemu_vsnprintf(char *buf, int buflen, const char *fmt, va_list args);
-void qemu_vprintf(const char *fmt, va_list ap);
-void qemu_printf(const char *fmt, ...);
-
-void *qemu_malloc(size_t size);
-void *qemu_mallocz(size_t size);
-void qemu_free(void *ptr);
-char *qemu_strdup(const char *str);
-
-void *get_mmap_addr(unsigned long size);
-
-/* specific kludges for OS compatibility (should be moved elsewhere) */
-#if defined(__i386__) && !defined(CONFIG_SOFTMMU) && !defined(CONFIG_USER_ONLY)
-
-/* disabled pthread version of longjmp which prevent us from using an
- alternative signal stack */
-extern void __longjmp(jmp_buf env, int val);
-#define longjmp __longjmp
-
-#include <signal.h>
-
-/* NOTE: it works only because the glibc sigset_t is >= kernel sigset_t */
-struct qemu_sigaction {
- union {
- void (*_sa_handler)(int);
- void (*_sa_sigaction)(int, struct siginfo *, void *);
- } _u;
- unsigned long sa_flags;
- void (*sa_restorer)(void);
- sigset_t sa_mask; /* mask last for extensibility */
-};
-
-int qemu_sigaction(int signum, const struct qemu_sigaction *act,
- struct qemu_sigaction *oldact);
-
-#undef sigaction
-#undef sa_handler
-#undef sa_sigaction
-#define sigaction qemu_sigaction
-#define sa_handler _u._sa_handler
-#define sa_sigaction _u._sa_sigaction
-
-#endif
-
-#endif
+++ /dev/null
-/* Code to mangle pathnames into those matching a given prefix.
- eg. open("/lib/foo.so") => open("/usr/gnemul/i386-linux/lib/foo.so");
-
- The assumption is that this area does not change.
-*/
-#include <sys/types.h>
-#include <dirent.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <stdio.h>
-#include "qemu.h"
-
-struct pathelem
-{
- /* Name of this, eg. lib */
- char *name;
- /* Full path name, eg. /usr/gnemul/x86-linux/lib. */
- char *pathname;
- struct pathelem *parent;
- /* Children */
- unsigned int num_entries;
- struct pathelem *entries[0];
-};
-
-static struct pathelem *base;
-
-/* First N chars of S1 match S2, and S2 is N chars long. */
-static int strneq(const char *s1, unsigned int n, const char *s2)
-{
- unsigned int i;
-
- for (i = 0; i < n; i++)
- if (s1[i] != s2[i])
- return 0;
- return s2[i] == 0;
-}
-
-static struct pathelem *add_entry(struct pathelem *root, const char *name);
-
-static struct pathelem *new_entry(const char *root,
- struct pathelem *parent,
- const char *name)
-{
- struct pathelem *new = malloc(sizeof(*new));
- new->name = strdup(name);
- asprintf(&new->pathname, "%s/%s", root, name);
- new->num_entries = 0;
- return new;
-}
-
-#define streq(a,b) (strcmp((a), (b)) == 0)
-
-static struct pathelem *add_dir_maybe(struct pathelem *path)
-{
- DIR *dir;
-
- if ((dir = opendir(path->pathname)) != NULL) {
- struct dirent *dirent;
-
- while ((dirent = readdir(dir)) != NULL) {
- if (!streq(dirent->d_name,".") && !streq(dirent->d_name,"..")){
- path = add_entry(path, dirent->d_name);
- }
- }
- closedir(dir);
- }
- return path;
-}
-
-static struct pathelem *add_entry(struct pathelem *root, const char *name)
-{
- root->num_entries++;
-
- root = realloc(root, sizeof(*root)
- + sizeof(root->entries[0])*root->num_entries);
-
- root->entries[root->num_entries-1] = new_entry(root->pathname, root, name);
- root->entries[root->num_entries-1]
- = add_dir_maybe(root->entries[root->num_entries-1]);
- return root;
-}
-
-/* This needs to be done after tree is stabalized (ie. no more reallocs!). */
-static void set_parents(struct pathelem *child, struct pathelem *parent)
-{
- unsigned int i;
-
- child->parent = parent;
- for (i = 0; i < child->num_entries; i++)
- set_parents(child->entries[i], child);
-}
-
-void init_paths(const char *prefix)
-{
- if (prefix[0] != '/' ||
- prefix[0] == '\0' ||
- !strcmp(prefix, "/"))
- return;
-
- base = new_entry("", NULL, prefix+1);
- base = add_dir_maybe(base);
- if (base->num_entries == 0) {
- free (base);
- base = NULL;
- } else {
- set_parents(base, base);
- }
-}
-
-/* FIXME: Doesn't handle DIR/.. where DIR is not in emulated dir. */
-static const char *
-follow_path(const struct pathelem *cursor, const char *name)
-{
- unsigned int i, namelen;
-
- name += strspn(name, "/");
- namelen = strcspn(name, "/");
-
- if (namelen == 0)
- return cursor->pathname;
-
- if (strneq(name, namelen, ".."))
- return follow_path(cursor->parent, name + namelen);
-
- if (strneq(name, namelen, "."))
- return follow_path(cursor, name + namelen);
-
- for (i = 0; i < cursor->num_entries; i++)
- if (strneq(name, namelen, cursor->entries[i]->name))
- return follow_path(cursor->entries[i], name + namelen);
-
- /* Not found */
- return NULL;
-}
-
-/* Look for path in emulation dir, otherwise return name. */
-const char *path(const char *name)
-{
- /* Only do absolute paths: quick and dirty, but should mostly be OK.
- Could do relative by tracking cwd. */
- if (!base || name[0] != '/')
- return name;
-
- return follow_path(base, name) ?: name;
-}
+++ /dev/null
-#!/bin/sh
-# enable automatic i386/ARM/SPARC/PPC program execution by the kernel
-
-# load the binfmt_misc module
-/sbin/modprobe binfmt_misc
-
-# probe cpu type
-cpu=`uname -m`
-case "$cpu" in
- i386|i486|i586|i686|i86pc|BePC)
- cpu="i386"
- ;;
- "Power Macintosh"|ppc|ppc64)
- cpu="ppc"
- ;;
- armv4l)
- cpu="arm"
- ;;
-esac
-
-# register the interpreter for each cpu except for the native one
-if [ $cpu != "i386" ] ; then
- echo ':i386:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x03\x00:\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfb\xff\xff\xff:/usr/local/bin/qemu-i386:' > /proc/sys/fs/binfmt_misc/register
- echo ':i486:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x06\x00:\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfb\xff\xff\xff:/usr/local/bin/qemu-i386:' > /proc/sys/fs/binfmt_misc/register
-fi
-if [ $cpu != "arm" ] ; then
- echo ':arm:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfb\xff\xff\xff:/usr/local/bin/qemu-arm:' > /proc/sys/fs/binfmt_misc/register
-fi
-if [ $cpu != "sparc" ] ; then
- echo ':sparc:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x02:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfb\xff\xff\xff:/usr/local/bin/qemu-sparc:' > /proc/sys/fs/binfmt_misc/register
-fi
-if [ $cpu != "ppc" ] ; then
- echo ':ppc:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x14:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfb\xff\xff\xff:/usr/local/bin/qemu-ppc:' > /proc/sys/fs/binfmt_misc/register
-fi
+++ /dev/null
-/*
- * create a COW disk image
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "vl.h"
-
-void *get_mmap_addr(unsigned long size)
-{
- return NULL;
-}
-
-void qemu_free(void *ptr)
-{
- free(ptr);
-}
-
-void *qemu_malloc(size_t size)
-{
- return malloc(size);
-}
-
-void *qemu_mallocz(size_t size)
-{
- void *ptr;
- ptr = qemu_malloc(size);
- if (!ptr)
- return NULL;
- memset(ptr, 0, size);
- return ptr;
-}
-
-char *qemu_strdup(const char *str)
-{
- char *ptr;
- ptr = qemu_malloc(strlen(str) + 1);
- if (!ptr)
- return NULL;
- strcpy(ptr, str);
- return ptr;
-}
-
-void pstrcpy(char *buf, int buf_size, const char *str)
-{
- int c;
- char *q = buf;
-
- if (buf_size <= 0)
- return;
-
- for(;;) {
- c = *str++;
- if (c == 0 || q >= buf + buf_size - 1)
- break;
- *q++ = c;
- }
- *q = '\0';
-}
-
-/* strcat and truncate. */
-char *pstrcat(char *buf, int buf_size, const char *s)
-{
- int len;
- len = strlen(buf);
- if (len < buf_size)
- pstrcpy(buf + len, buf_size - len, s);
- return buf;
-}
-
-int strstart(const char *str, const char *val, const char **ptr)
-{
- const char *p, *q;
- p = str;
- q = val;
- while (*q != '\0') {
- if (*p != *q)
- return 0;
- p++;
- q++;
- }
- if (ptr)
- *ptr = p;
- return 1;
-}
-
-void term_printf(const char *fmt, ...)
-{
- va_list ap;
- va_start(ap, fmt);
- vprintf(fmt, ap);
- va_end(ap);
-}
-
-void __attribute__((noreturn)) error(const char *fmt, ...)
-{
- va_list ap;
- va_start(ap, fmt);
- fprintf(stderr, "qemu-img: ");
- vfprintf(stderr, fmt, ap);
- fprintf(stderr, "\n");
- exit(1);
- va_end(ap);
-}
-
-static void format_print(void *opaque, const char *name)
-{
- printf(" %s", name);
-}
-
-void help(void)
-{
- printf("qemu-img version " QEMU_VERSION ", Copyright (c) 2004 Fabrice Bellard\n"
- "usage: qemu-img command [command options]\n"
- "QEMU disk image utility\n"
- "\n"
- "Command syntax:\n"
- " create [-e] [-b base_image] [-f fmt] filename [size]\n"
- " commit [-f fmt] filename\n"
- " convert [-c] [-e] [-f fmt] filename [-O output_fmt] output_filename\n"
- " info [-f fmt] filename\n"
- "\n"
- "Command parameters:\n"
- " 'filename' is a disk image filename\n"
- " 'base_image' is the read-only disk image which is used as base for a copy on\n"
- " write image; the copy on write image only stores the modified data\n"
- " 'fmt' is the disk image format. It is guessed automatically in most cases\n"
- " 'size' is the disk image size in kilobytes. Optional suffixes 'M' (megabyte)\n"
- " and 'G' (gigabyte) are supported\n"
- " 'output_filename' is the destination disk image filename\n"
- " 'output_fmt' is the destination format\n"
- " '-c' indicates that target image must be compressed (qcow format only)\n"
- " '-e' indicates that the target image must be encrypted (qcow format only)\n"
- );
- printf("\nSupported format:");
- bdrv_iterate_format(format_print, NULL);
- printf("\n");
- exit(1);
-}
-
-
-#define NB_SUFFIXES 4
-
-static void get_human_readable_size(char *buf, int buf_size, int64_t size)
-{
- char suffixes[NB_SUFFIXES] = "KMGT";
- int64_t base;
- int i;
-
- if (size <= 999) {
- snprintf(buf, buf_size, "%lld", size);
- } else {
- base = 1024;
- for(i = 0; i < NB_SUFFIXES; i++) {
- if (size < (10 * base)) {
- snprintf(buf, buf_size, "%0.1f%c",
- (double)size / base,
- suffixes[i]);
- break;
- } else if (size < (1000 * base) || i == (NB_SUFFIXES - 1)) {
- snprintf(buf, buf_size, "%lld%c",
- (size + (base >> 1)) / base,
- suffixes[i]);
- break;
- }
- base = base * 1024;
- }
- }
-}
-
-#if defined(WIN32)
-/* XXX: put correct support for win32 */
-static int read_password(char *buf, int buf_size)
-{
- int c, i;
- printf("Password: ");
- fflush(stdout);
- i = 0;
- for(;;) {
- c = getchar();
- if (c == '\n')
- break;
- if (i < (buf_size - 1))
- buf[i++] = c;
- }
- buf[i] = '\0';
- return 0;
-}
-
-#else
-
-#include <termios.h>
-
-static struct termios oldtty;
-
-static void term_exit(void)
-{
- tcsetattr (0, TCSANOW, &oldtty);
-}
-
-static void term_init(void)
-{
- struct termios tty;
-
- tcgetattr (0, &tty);
- oldtty = tty;
-
- tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
- |INLCR|IGNCR|ICRNL|IXON);
- tty.c_oflag |= OPOST;
- tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN);
- tty.c_cflag &= ~(CSIZE|PARENB);
- tty.c_cflag |= CS8;
- tty.c_cc[VMIN] = 1;
- tty.c_cc[VTIME] = 0;
-
- tcsetattr (0, TCSANOW, &tty);
-
- atexit(term_exit);
-}
-
-int read_password(char *buf, int buf_size)
-{
- uint8_t ch;
- int i, ret;
-
- printf("password: ");
- fflush(stdout);
- term_init();
- i = 0;
- for(;;) {
- ret = read(0, &ch, 1);
- if (ret == -1) {
- if (errno == EAGAIN || errno == EINTR) {
- continue;
- } else {
- ret = -1;
- break;
- }
- } else if (ret == 0) {
- ret = -1;
- break;
- } else {
- if (ch == '\r') {
- ret = 0;
- break;
- }
- if (i < (buf_size - 1))
- buf[i++] = ch;
- }
- }
- term_exit();
- buf[i] = '\0';
- printf("\n");
- return ret;
-}
-#endif
-
-static BlockDriverState *bdrv_new_open(const char *filename,
- const char *fmt)
-{
- BlockDriverState *bs;
- BlockDriver *drv;
- char password[256];
-
- bs = bdrv_new("");
- if (!bs)
- error("Not enough memory");
- if (fmt) {
- drv = bdrv_find_format(fmt);
- if (!drv)
- error("Unknown file format '%s'", fmt);
- } else {
- drv = NULL;
- }
- if (bdrv_open2(bs, filename, 0, drv) < 0) {
- error("Could not open '%s'", filename);
- }
- if (bdrv_is_encrypted(bs)) {
- printf("Disk image '%s' is encrypted.\n", filename);
- if (read_password(password, sizeof(password)) < 0)
- error("No password given");
- if (bdrv_set_key(bs, password) < 0)
- error("invalid password");
- }
- return bs;
-}
-
-static int img_create(int argc, char **argv)
-{
- int c, ret, encrypted;
- const char *fmt = "raw";
- const char *filename;
- const char *base_filename = NULL;
- int64_t size;
- const char *p;
- BlockDriver *drv;
-
- encrypted = 0;
- for(;;) {
- c = getopt(argc, argv, "b:f:he");
- if (c == -1)
- break;
- switch(c) {
- case 'h':
- help();
- break;
- case 'b':
- base_filename = optarg;
- break;
- case 'f':
- fmt = optarg;
- break;
- case 'e':
- encrypted = 1;
- break;
- }
- }
- if (optind >= argc)
- help();
- filename = argv[optind++];
- size = 0;
- if (base_filename) {
- BlockDriverState *bs;
- bs = bdrv_new_open(base_filename, NULL);
- bdrv_get_geometry(bs, &size);
- size *= 512;
- bdrv_delete(bs);
- } else {
- if (optind >= argc)
- help();
- p = argv[optind];
- size = strtoul(p, (char **)&p, 0);
- if (*p == 'M') {
- size *= 1024 * 1024;
- } else if (*p == 'G') {
- size *= 1024 * 1024 * 1024;
- } else if (*p == 'k' || *p == 'K' || *p == '\0') {
- size *= 1024;
- } else {
- help();
- }
- }
- drv = bdrv_find_format(fmt);
- if (!drv)
- error("Unknown file format '%s'", fmt);
- printf("Formating '%s', fmt=%s",
- filename, fmt);
- if (encrypted)
- printf(", encrypted");
- if (base_filename) {
- printf(", backing_file=%s",
- base_filename);
- }
- printf(", size=%lld kB\n", size / 1024);
- ret = bdrv_create(drv, filename, size / 512, base_filename, encrypted);
- if (ret < 0) {
- if (ret == -ENOTSUP) {
- error("Formatting or formatting option not supported for file format '%s'", fmt);
- } else {
- error("Error while formatting");
- }
- }
- return 0;
-}
-
-static int img_commit(int argc, char **argv)
-{
- int c, ret;
- const char *filename, *fmt;
- BlockDriver *drv;
- BlockDriverState *bs;
-
- fmt = NULL;
- for(;;) {
- c = getopt(argc, argv, "f:h");
- if (c == -1)
- break;
- switch(c) {
- case 'h':
- help();
- break;
- case 'f':
- fmt = optarg;
- break;
- }
- }
- if (optind >= argc)
- help();
- filename = argv[optind++];
-
- bs = bdrv_new("");
- if (!bs)
- error("Not enough memory");
- if (fmt) {
- drv = bdrv_find_format(fmt);
- if (!drv)
- error("Unknown file format '%s'", fmt);
- } else {
- drv = NULL;
- }
- if (bdrv_open2(bs, filename, 0, drv) < 0) {
- error("Could not open '%s'", filename);
- }
- ret = bdrv_commit(bs);
- switch(ret) {
- case 0:
- printf("Image committed.\n");
- break;
- case -ENOENT:
- error("No disk inserted");
- break;
- case -EACCES:
- error("Image is read-only");
- break;
- case -ENOTSUP:
- error("Image is already committed");
- break;
- default:
- error("Error while committing image");
- break;
- }
-
- bdrv_delete(bs);
- return 0;
-}
-
-static int is_not_zero(const uint8_t *sector, int len)
-{
- int i;
- len >>= 2;
- for(i = 0;i < len; i++) {
- if (((uint32_t *)sector)[i] != 0)
- return 1;
- }
- return 0;
-}
-
-static int is_allocated_sectors(const uint8_t *buf, int n, int *pnum)
-{
- int v, i;
-
- if (n <= 0) {
- *pnum = 0;
- return 0;
- }
- v = is_not_zero(buf, 512);
- for(i = 1; i < n; i++) {
- buf += 512;
- if (v != is_not_zero(buf, 512))
- break;
- }
- *pnum = i;
- return v;
-}
-
-#define IO_BUF_SIZE 65536
-
-static int img_convert(int argc, char **argv)
-{
- int c, ret, n, n1, compress, cluster_size, cluster_sectors, encrypt;
- const char *filename, *fmt, *out_fmt, *out_filename;
- BlockDriver *drv;
- BlockDriverState *bs, *out_bs;
- int64_t total_sectors, nb_sectors, sector_num;
- uint8_t buf[IO_BUF_SIZE];
- const uint8_t *buf1;
-
- fmt = NULL;
- out_fmt = "raw";
- compress = 0;
- encrypt = 0;
- for(;;) {
- c = getopt(argc, argv, "f:O:hce");
- if (c == -1)
- break;
- switch(c) {
- case 'h':
- help();
- break;
- case 'f':
- fmt = optarg;
- break;
- case 'O':
- out_fmt = optarg;
- break;
- case 'c':
- compress = 1;
- break;
- case 'e':
- encrypt = 1;
- break;
- }
- }
- if (optind >= argc)
- help();
- filename = argv[optind++];
- if (optind >= argc)
- help();
- out_filename = argv[optind++];
-
- bs = bdrv_new_open(filename, fmt);
-
- drv = bdrv_find_format(out_fmt);
- if (!drv)
- error("Unknown file format '%s'", fmt);
- if (compress && drv != &bdrv_qcow)
- error("Compression not supported for this file format");
- if (encrypt && drv != &bdrv_qcow)
- error("Encryption not supported for this file format");
- if (compress && encrypt)
- error("Compression and encryption not supported at the same time");
- bdrv_get_geometry(bs, &total_sectors);
- ret = bdrv_create(drv, out_filename, total_sectors, NULL, encrypt);
- if (ret < 0) {
- if (ret == -ENOTSUP) {
- error("Formatting not supported for file format '%s'", fmt);
- } else {
- error("Error while formatting '%s'", out_filename);
- }
- }
-
- out_bs = bdrv_new_open(out_filename, out_fmt);
-
- if (compress) {
- cluster_size = qcow_get_cluster_size(out_bs);
- if (cluster_size <= 0 || cluster_size > IO_BUF_SIZE)
- error("invalid cluster size");
- cluster_sectors = cluster_size >> 9;
- sector_num = 0;
- for(;;) {
- nb_sectors = total_sectors - sector_num;
- if (nb_sectors <= 0)
- break;
- if (nb_sectors >= cluster_sectors)
- n = cluster_sectors;
- else
- n = nb_sectors;
- if (bdrv_read(bs, sector_num, buf, n) < 0)
- error("error while reading");
- if (n < cluster_sectors)
- memset(buf + n * 512, 0, cluster_size - n * 512);
- if (is_not_zero(buf, cluster_size)) {
- if (qcow_compress_cluster(out_bs, sector_num, buf) != 0)
- error("error while compressing sector %lld", sector_num);
- }
- sector_num += n;
- }
- } else {
- sector_num = 0;
- for(;;) {
- nb_sectors = total_sectors - sector_num;
- if (nb_sectors <= 0)
- break;
- if (nb_sectors >= (IO_BUF_SIZE / 512))
- n = (IO_BUF_SIZE / 512);
- else
- n = nb_sectors;
- if (bdrv_read(bs, sector_num, buf, n) < 0)
- error("error while reading");
- /* NOTE: at the same time we convert, we do not write zero
- sectors to have a chance to compress the image. Ideally, we
- should add a specific call to have the info to go faster */
- buf1 = buf;
- while (n > 0) {
- if (is_allocated_sectors(buf1, n, &n1)) {
- if (bdrv_write(out_bs, sector_num, buf1, n1) < 0)
- error("error while writing");
- }
- sector_num += n1;
- n -= n1;
- buf1 += n1 * 512;
- }
- }
- }
- bdrv_delete(out_bs);
- bdrv_delete(bs);
- return 0;
-}
-
-#ifdef _WIN32
-static int64_t get_allocated_file_size(const char *filename)
-{
- struct _stati64 st;
- if (_stati64(filename, &st) < 0)
- return -1;
- return st.st_size;
-}
-#else
-static int64_t get_allocated_file_size(const char *filename)
-{
- struct stat st;
- if (stat(filename, &st) < 0)
- return -1;
- return (int64_t)st.st_blocks * 512;
-}
-#endif
-
-static int img_info(int argc, char **argv)
-{
- int c;
- const char *filename, *fmt;
- BlockDriver *drv;
- BlockDriverState *bs;
- char fmt_name[128], size_buf[128], dsize_buf[128];
- int64_t total_sectors, allocated_size;
-
- fmt = NULL;
- for(;;) {
- c = getopt(argc, argv, "f:h");
- if (c == -1)
- break;
- switch(c) {
- case 'h':
- help();
- break;
- case 'f':
- fmt = optarg;
- break;
- }
- }
- if (optind >= argc)
- help();
- filename = argv[optind++];
-
- bs = bdrv_new("");
- if (!bs)
- error("Not enough memory");
- if (fmt) {
- drv = bdrv_find_format(fmt);
- if (!drv)
- error("Unknown file format '%s'", fmt);
- } else {
- drv = NULL;
- }
- if (bdrv_open2(bs, filename, 0, drv) < 0) {
- error("Could not open '%s'", filename);
- }
- bdrv_get_format(bs, fmt_name, sizeof(fmt_name));
- bdrv_get_geometry(bs, &total_sectors);
- get_human_readable_size(size_buf, sizeof(size_buf), total_sectors * 512);
- allocated_size = get_allocated_file_size(filename);
- if (allocated_size < 0)
- error("Could not get file size '%s'", filename);
- get_human_readable_size(dsize_buf, sizeof(dsize_buf),
- allocated_size);
- printf("image: %s\n"
- "file format: %s\n"
- "virtual size: %s (%lld bytes)\n"
- "disk size: %s\n",
- filename, fmt_name, size_buf,
- total_sectors * 512,
- dsize_buf);
- if (bdrv_is_encrypted(bs))
- printf("encrypted: yes\n");
- bdrv_delete(bs);
- return 0;
-}
-
-int main(int argc, char **argv)
-{
- const char *cmd;
-
- bdrv_init();
- if (argc < 2)
- help();
- cmd = argv[1];
- optind++;
- if (!strcmp(cmd, "create")) {
- img_create(argc, argv);
- } else if (!strcmp(cmd, "commit")) {
- img_commit(argc, argv);
- } else if (!strcmp(cmd, "convert")) {
- img_convert(argc, argv);
- } else if (!strcmp(cmd, "info")) {
- img_info(argc, argv);
- } else {
- help();
- }
- return 0;
-}
+++ /dev/null
-/*
- * QEMU readline utility
- *
- * Copyright (c) 2003-2004 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "vl.h"
-
-#define TERM_CMD_BUF_SIZE 4095
-#define TERM_MAX_CMDS 64
-#define NB_COMPLETIONS_MAX 256
-
-#define IS_NORM 0
-#define IS_ESC 1
-#define IS_CSI 2
-
-#define printf do_not_use_printf
-
-static char term_cmd_buf[TERM_CMD_BUF_SIZE + 1];
-static int term_cmd_buf_index;
-static int term_cmd_buf_size;
-
-static char term_last_cmd_buf[TERM_CMD_BUF_SIZE + 1];
-static int term_last_cmd_buf_index;
-static int term_last_cmd_buf_size;
-
-static int term_esc_state;
-static int term_esc_param;
-
-static char *term_history[TERM_MAX_CMDS];
-static int term_hist_entry = -1;
-
-static int nb_completions;
-int completion_index;
-static char *completions[NB_COMPLETIONS_MAX];
-
-static ReadLineFunc *term_readline_func;
-static int term_is_password;
-static char term_prompt[256];
-static void *term_readline_opaque;
-
-static void term_show_prompt2(void)
-{
- term_printf("%s", term_prompt);
- term_flush();
- term_last_cmd_buf_index = 0;
- term_last_cmd_buf_size = 0;
- term_esc_state = IS_NORM;
-}
-
-static void term_show_prompt(void)
-{
- term_show_prompt2();
- term_cmd_buf_index = 0;
- term_cmd_buf_size = 0;
-}
-
-/* update the displayed command line */
-static void term_update(void)
-{
- int i, delta, len;
-
- if (term_cmd_buf_size != term_last_cmd_buf_size ||
- memcmp(term_cmd_buf, term_last_cmd_buf, term_cmd_buf_size) != 0) {
- for(i = 0; i < term_last_cmd_buf_index; i++) {
- term_printf("\033[D");
- }
- term_cmd_buf[term_cmd_buf_size] = '\0';
- if (term_is_password) {
- len = strlen(term_cmd_buf);
- for(i = 0; i < len; i++)
- term_printf("*");
- } else {
- term_printf("%s", term_cmd_buf);
- }
- term_printf("\033[K");
- memcpy(term_last_cmd_buf, term_cmd_buf, term_cmd_buf_size);
- term_last_cmd_buf_size = term_cmd_buf_size;
- term_last_cmd_buf_index = term_cmd_buf_size;
- }
- if (term_cmd_buf_index != term_last_cmd_buf_index) {
- delta = term_cmd_buf_index - term_last_cmd_buf_index;
- if (delta > 0) {
- for(i = 0;i < delta; i++) {
- term_printf("\033[C");
- }
- } else {
- delta = -delta;
- for(i = 0;i < delta; i++) {
- term_printf("\033[D");
- }
- }
- term_last_cmd_buf_index = term_cmd_buf_index;
- }
- term_flush();
-}
-
-static void term_insert_char(int ch)
-{
- if (term_cmd_buf_index < TERM_CMD_BUF_SIZE) {
- memmove(term_cmd_buf + term_cmd_buf_index + 1,
- term_cmd_buf + term_cmd_buf_index,
- term_cmd_buf_size - term_cmd_buf_index);
- term_cmd_buf[term_cmd_buf_index] = ch;
- term_cmd_buf_size++;
- term_cmd_buf_index++;
- }
-}
-
-static void term_backward_char(void)
-{
- if (term_cmd_buf_index > 0) {
- term_cmd_buf_index--;
- }
-}
-
-static void term_forward_char(void)
-{
- if (term_cmd_buf_index < term_cmd_buf_size) {
- term_cmd_buf_index++;
- }
-}
-
-static void term_delete_char(void)
-{
- if (term_cmd_buf_index < term_cmd_buf_size) {
- memmove(term_cmd_buf + term_cmd_buf_index,
- term_cmd_buf + term_cmd_buf_index + 1,
- term_cmd_buf_size - term_cmd_buf_index - 1);
- term_cmd_buf_size--;
- }
-}
-
-static void term_backspace(void)
-{
- if (term_cmd_buf_index > 0) {
- term_backward_char();
- term_delete_char();
- }
-}
-
-static void term_bol(void)
-{
- term_cmd_buf_index = 0;
-}
-
-static void term_eol(void)
-{
- term_cmd_buf_index = term_cmd_buf_size;
-}
-
-static void term_up_char(void)
-{
- int idx;
-
- if (term_hist_entry == 0)
- return;
- if (term_hist_entry == -1) {
- /* Find latest entry */
- for (idx = 0; idx < TERM_MAX_CMDS; idx++) {
- if (term_history[idx] == NULL)
- break;
- }
- term_hist_entry = idx;
- }
- term_hist_entry--;
- if (term_hist_entry >= 0) {
- pstrcpy(term_cmd_buf, sizeof(term_cmd_buf),
- term_history[term_hist_entry]);
- term_cmd_buf_index = term_cmd_buf_size = strlen(term_cmd_buf);
- }
-}
-
-static void term_down_char(void)
-{
- if (term_hist_entry == TERM_MAX_CMDS - 1 || term_hist_entry == -1)
- return;
- if (term_history[++term_hist_entry] != NULL) {
- pstrcpy(term_cmd_buf, sizeof(term_cmd_buf),
- term_history[term_hist_entry]);
- } else {
- term_hist_entry = -1;
- }
- term_cmd_buf_index = term_cmd_buf_size = strlen(term_cmd_buf);
-}
-
-static void term_hist_add(const char *cmdline)
-{
- char *hist_entry, *new_entry;
- int idx;
-
- if (cmdline[0] == '\0')
- return;
- new_entry = NULL;
- if (term_hist_entry != -1) {
- /* We were editing an existing history entry: replace it */
- hist_entry = term_history[term_hist_entry];
- idx = term_hist_entry;
- if (strcmp(hist_entry, cmdline) == 0) {
- goto same_entry;
- }
- }
- /* Search cmdline in history buffers */
- for (idx = 0; idx < TERM_MAX_CMDS; idx++) {
- hist_entry = term_history[idx];
- if (hist_entry == NULL)
- break;
- if (strcmp(hist_entry, cmdline) == 0) {
- same_entry:
- new_entry = hist_entry;
- /* Put this entry at the end of history */
- memmove(&term_history[idx], &term_history[idx + 1],
- &term_history[TERM_MAX_CMDS] - &term_history[idx + 1]);
- term_history[TERM_MAX_CMDS - 1] = NULL;
- for (; idx < TERM_MAX_CMDS; idx++) {
- if (term_history[idx] == NULL)
- break;
- }
- break;
- }
- }
- if (idx == TERM_MAX_CMDS) {
- /* Need to get one free slot */
- free(term_history[0]);
- memcpy(term_history, &term_history[1],
- &term_history[TERM_MAX_CMDS] - &term_history[1]);
- term_history[TERM_MAX_CMDS - 1] = NULL;
- idx = TERM_MAX_CMDS - 1;
- }
- if (new_entry == NULL)
- new_entry = strdup(cmdline);
- term_history[idx] = new_entry;
- term_hist_entry = -1;
-}
-
-/* completion support */
-
-void add_completion(const char *str)
-{
- if (nb_completions < NB_COMPLETIONS_MAX) {
- completions[nb_completions++] = qemu_strdup(str);
- }
-}
-
-static void term_completion(void)
-{
- int len, i, j, max_width, nb_cols;
- char *cmdline;
-
- nb_completions = 0;
-
- cmdline = qemu_malloc(term_cmd_buf_index + 1);
- if (!cmdline)
- return;
- memcpy(cmdline, term_cmd_buf, term_cmd_buf_index);
- cmdline[term_cmd_buf_index] = '\0';
- qemu_free(cmdline);
-
- /* no completion found */
- if (nb_completions <= 0)
- return;
- if (nb_completions == 1) {
- len = strlen(completions[0]);
- for(i = completion_index; i < len; i++) {
- term_insert_char(completions[0][i]);
- }
- /* extra space for next argument. XXX: make it more generic */
- if (len > 0 && completions[0][len - 1] != '/')
- term_insert_char(' ');
- } else {
- term_printf("\n");
- max_width = 0;
- for(i = 0; i < nb_completions; i++) {
- len = strlen(completions[i]);
- if (len > max_width)
- max_width = len;
- }
- max_width += 2;
- if (max_width < 10)
- max_width = 10;
- else if (max_width > 80)
- max_width = 80;
- nb_cols = 80 / max_width;
- j = 0;
- for(i = 0; i < nb_completions; i++) {
- term_printf("%-*s", max_width, completions[i]);
- if (++j == nb_cols || i == (nb_completions - 1)) {
- term_printf("\n");
- j = 0;
- }
- }
- term_show_prompt2();
- }
-}
-
-/* return true if command handled */
-void readline_handle_byte(int ch)
-{
- switch(term_esc_state) {
- case IS_NORM:
- switch(ch) {
- case 1:
- term_bol();
- break;
- case 4:
- term_delete_char();
- break;
- case 5:
- term_eol();
- break;
- case 9:
- term_completion();
- break;
- case 10:
- case 13:
- term_cmd_buf[term_cmd_buf_size] = '\0';
- if (!term_is_password)
- term_hist_add(term_cmd_buf);
- term_printf("\n");
- /* NOTE: readline_start can be called here */
- term_readline_func(term_readline_opaque, term_cmd_buf);
- break;
- case 27:
- term_esc_state = IS_ESC;
- break;
- case 127:
- case 8:
- term_backspace();
- break;
- case 155:
- term_esc_state = IS_CSI;
- break;
- default:
- if (ch >= 32) {
- term_insert_char(ch);
- }
- break;
- }
- break;
- case IS_ESC:
- if (ch == '[') {
- term_esc_state = IS_CSI;
- term_esc_param = 0;
- } else {
- term_esc_state = IS_NORM;
- }
- break;
- case IS_CSI:
- switch(ch) {
- case 'A':
- case 'F':
- term_up_char();
- break;
- case 'B':
- case 'E':
- term_down_char();
- break;
- case 'D':
- term_backward_char();
- break;
- case 'C':
- term_forward_char();
- break;
- case '0' ... '9':
- term_esc_param = term_esc_param * 10 + (ch - '0');
- goto the_end;
- case '~':
- switch(term_esc_param) {
- case 1:
- term_bol();
- break;
- case 3:
- term_delete_char();
- break;
- case 4:
- term_eol();
- break;
- }
- break;
- default:
- break;
- }
- term_esc_state = IS_NORM;
- the_end:
- break;
- }
- term_update();
-}
-
-void readline_start(const char *prompt, int is_password,
- ReadLineFunc *readline_func, void *opaque)
-{
- pstrcpy(term_prompt, sizeof(term_prompt), prompt);
- term_readline_func = readline_func;
- term_readline_opaque = opaque;
- term_is_password = is_password;
- term_show_prompt();
-}
-
-const char *readline_get_history(unsigned int index)
-{
- if (index >= TERM_MAX_CMDS)
- return NULL;
- return term_history[index];
-}
-
-
+++ /dev/null
-/*
- * QEMU SDL display driver
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "vl.h"
-
-#include <SDL.h>
-
-/* keyboard stuff */
-#include <SDL_keysym.h>
-#include "keysym_adapter_sdl.h"
-#include "keyboard_rdesktop.c"
-
-#ifndef _WIN32
-#include <signal.h>
-#endif
-
-#if defined(__APPLE__)
-#define CONFIG_SDL_GENERIC_KBD
-#endif
-
-static SDL_Surface *screen;
-static int gui_grab; /* if true, all keyboard/mouse events are grabbed */
-static int last_vm_running;
-static int gui_saved_grab;
-static int gui_fullscreen;
-static int gui_key_modifier_pressed;
-static int gui_keysym;
-static void* kbd_layout=0;
-static int gui_fullscreen_initial_grab;
-static int gui_grab_code = KMOD_LALT | KMOD_LCTRL;
-static uint8_t modifiers_state[256];
-static int width, height;
-static SDL_Cursor *sdl_cursor_normal;
-static SDL_Cursor *sdl_cursor_hidden;
-static int absolute_enabled = 0;
-
-SDL_PixelFormat* sdl_get_format(void) {
- return screen->format;
-}
-
-static void sdl_update(DisplayState *ds, int x, int y, int w, int h)
-{
- SDL_UpdateRect(screen, x, y, w, h);
-}
-
-static void sdl_resize(DisplayState *ds, int w, int h)
-{
- int flags;
-
- // printf("resizing to %d %d\n", w, h);
-
- flags = SDL_HWSURFACE|SDL_ASYNCBLIT|SDL_HWACCEL;
- flags |= SDL_RESIZABLE;
- if (gui_fullscreen)
- flags |= SDL_FULLSCREEN;
- width = w;
- height = h;
- screen = SDL_SetVideoMode(w, h, 0, flags);
- if (!screen) {
- fprintf(stderr, "Could not open SDL display\n");
- exit(1);
- }
- ds->data = screen->pixels;
- ds->linesize = screen->pitch;
- ds->depth = screen->format->BitsPerPixel;
- ds->width = w;
- ds->height = h;
-}
-
-#ifdef CONFIG_SDL_GENERIC_KBD
-
-/* XXX: use keymap tables defined in the VNC patch because the
- following code suppose you have a US keyboard. */
-
-static const uint8_t scancodes[SDLK_LAST] = {
- [SDLK_ESCAPE] = 0x01,
- [SDLK_1] = 0x02,
- [SDLK_2] = 0x03,
- [SDLK_3] = 0x04,
- [SDLK_4] = 0x05,
- [SDLK_5] = 0x06,
- [SDLK_6] = 0x07,
- [SDLK_7] = 0x08,
- [SDLK_8] = 0x09,
- [SDLK_9] = 0x0a,
- [SDLK_0] = 0x0b,
- [SDLK_MINUS] = 0x0c,
- [SDLK_EQUALS] = 0x0d,
- [SDLK_BACKSPACE] = 0x0e,
- [SDLK_TAB] = 0x0f,
- [SDLK_q] = 0x10,
- [SDLK_w] = 0x11,
- [SDLK_e] = 0x12,
- [SDLK_r] = 0x13,
- [SDLK_t] = 0x14,
- [SDLK_y] = 0x15,
- [SDLK_u] = 0x16,
- [SDLK_i] = 0x17,
- [SDLK_o] = 0x18,
- [SDLK_p] = 0x19,
- [SDLK_LEFTBRACKET] = 0x1a,
- [SDLK_RIGHTBRACKET] = 0x1b,
- [SDLK_RETURN] = 0x1c,
- [SDLK_LCTRL] = 0x1d,
- [SDLK_a] = 0x1e,
- [SDLK_s] = 0x1f,
- [SDLK_d] = 0x20,
- [SDLK_f] = 0x21,
- [SDLK_g] = 0x22,
- [SDLK_h] = 0x23,
- [SDLK_j] = 0x24,
- [SDLK_k] = 0x25,
- [SDLK_l] = 0x26,
- [SDLK_SEMICOLON] = 0x27,
- [SDLK_QUOTE] = 0x28,
- [SDLK_BACKQUOTE] = 0x29,
- [SDLK_LSHIFT] = 0x2a,
- [SDLK_BACKSLASH] = 0x2b,
- [SDLK_z] = 0x2c,
- [SDLK_x] = 0x2d,
- [SDLK_c] = 0x2e,
- [SDLK_v] = 0x2f,
- [SDLK_b] = 0x30,
- [SDLK_n] = 0x31,
- [SDLK_m] = 0x32,
- [SDLK_COMMA] = 0x33,
- [SDLK_PERIOD] = 0x34,
- [SDLK_SLASH] = 0x35,
- [SDLK_KP_MULTIPLY] = 0x37,
- [SDLK_LALT] = 0x38,
- [SDLK_SPACE] = 0x39,
- [SDLK_CAPSLOCK] = 0x3a,
- [SDLK_F1] = 0x3b,
- [SDLK_F2] = 0x3c,
- [SDLK_F3] = 0x3d,
- [SDLK_F4] = 0x3e,
- [SDLK_F5] = 0x3f,
- [SDLK_F6] = 0x40,
- [SDLK_F7] = 0x41,
- [SDLK_F8] = 0x42,
- [SDLK_F9] = 0x43,
- [SDLK_F10] = 0x44,
- [SDLK_NUMLOCK] = 0x45,
- [SDLK_SCROLLOCK] = 0x46,
- [SDLK_KP7] = 0x47,
- [SDLK_KP8] = 0x48,
- [SDLK_KP9] = 0x49,
- [SDLK_KP_MINUS] = 0x4a,
- [SDLK_KP4] = 0x4b,
- [SDLK_KP5] = 0x4c,
- [SDLK_KP6] = 0x4d,
- [SDLK_KP_PLUS] = 0x4e,
- [SDLK_KP1] = 0x4f,
- [SDLK_KP2] = 0x50,
- [SDLK_KP3] = 0x51,
- [SDLK_KP0] = 0x52,
- [SDLK_KP_PERIOD] = 0x53,
- [SDLK_PRINT] = 0x54,
- [SDLK_LMETA] = 0x56,
-
- [SDLK_KP_ENTER] = 0x9c,
- [SDLK_KP_DIVIDE] = 0xb5,
-
- [SDLK_UP] = 0xc8,
- [SDLK_DOWN] = 0xd0,
- [SDLK_RIGHT] = 0xcd,
- [SDLK_LEFT] = 0xcb,
- [SDLK_INSERT] = 0xd2,
- [SDLK_HOME] = 0xc7,
- [SDLK_END] = 0xcf,
- [SDLK_PAGEUP] = 0xc9,
- [SDLK_PAGEDOWN] = 0xd1,
- [SDLK_DELETE] = 0xd3,
-};
-
-static uint8_t sdl_keyevent_to_keycode(const SDL_KeyboardEvent *ev)
-{
- return scancodes[ev->keysym.sym];
-}
-
-#elif defined(_WIN32)
-
-static uint8_t sdl_keyevent_to_keycode(const SDL_KeyboardEvent *ev)
-{
- return ev->keysym.scancode;
-}
-
-#else
-
-static const uint8_t x_keycode_to_pc_keycode[61] = {
- 0xc7, /* 97 Home */
- 0xc8, /* 98 Up */
- 0xc9, /* 99 PgUp */
- 0xcb, /* 100 Left */
- 0x4c, /* 101 KP-5 */
- 0xcd, /* 102 Right */
- 0xcf, /* 103 End */
- 0xd0, /* 104 Down */
- 0xd1, /* 105 PgDn */
- 0xd2, /* 106 Ins */
- 0xd3, /* 107 Del */
- 0x9c, /* 108 Enter */
- 0x9d, /* 109 Ctrl-R */
- 0x0, /* 110 Pause */
- 0xb7, /* 111 Print */
- 0xb5, /* 112 Divide */
- 0xb8, /* 113 Alt-R */
- 0xc6, /* 114 Break */
- 0x0, /* 115 */
- 0x0, /* 116 */
- 0x0, /* 117 */
- 0x0, /* 118 */
- 0x0, /* 119 */
- 0x70, /* 120 Hiragana_Katakana */
- 0x0, /* 121 */
- 0x0, /* 122 */
- 0x73, /* 123 backslash */
- 0x0, /* 124 */
- 0x0, /* 125 */
- 0x0, /* 126 */
- 0x0, /* 127 */
- 0x0, /* 128 */
- 0x79, /* 129 Henkan */
- 0x0, /* 130 */
- 0x7b, /* 131 Muhenkan */
- 0x0, /* 132 */
- 0x7d, /* 133 Yen */
- 0x0, /* 134 */
- 0x0, /* 135 */
- 0x47, /* 136 KP_7 */
- 0x48, /* 137 KP_8 */
- 0x49, /* 138 KP_9 */
- 0x4b, /* 139 KP_4 */
- 0x4c, /* 140 KP_5 */
- 0x4d, /* 141 KP_6 */
- 0x4f, /* 142 KP_1 */
- 0x50, /* 143 KP_2 */
- 0x51, /* 144 KP_3 */
- 0x52, /* 145 KP_0 */
- 0x53, /* 146 KP_. */
- 0x47, /* 147 KP_HOME */
- 0x48, /* 148 KP_UP */
- 0x49, /* 149 KP_PgUp */
- 0x4b, /* 150 KP_Left */
- 0x4c, /* 151 KP_ */
- 0x4d, /* 152 KP_Right */
- 0x4f, /* 153 KP_End */
- 0x50, /* 154 KP_Down */
- 0x51, /* 155 KP_PgDn */
- 0x52, /* 156 KP_Ins */
- 0x53, /* 157 KP_Del */
-};
-
-static uint8_t sdl_keyevent_to_keycode(const SDL_KeyboardEvent *ev)
-{
- int keycode;
-
- keycode = ev->keysym.scancode;
-
- if (keycode < 9) {
- keycode = 0;
- } else if (keycode < 97) {
- keycode -= 8; /* just an offset */
- } else if (keycode < 158) {
- /* use conversion table */
- keycode = x_keycode_to_pc_keycode[keycode - 97];
- } else {
- keycode = 0;
- }
- return keycode;
-}
-
-#endif
-
-static void reset_keys(void)
-{
- int i;
- for(i = 0; i < 256; i++) {
- if (modifiers_state[i]) {
- if (i & 0x80)
- kbd_put_keycode(0xe0);
- kbd_put_keycode(i | 0x80);
- modifiers_state[i] = 0;
- }
- }
-}
-
-static void sdl_process_key(SDL_KeyboardEvent *ev)
-{
- int keycode, v;
-
- if(kbd_layout)
- keycode=keysym2scancode(kbd_layout, ev->keysym.sym);
- else {
-
- if (ev->keysym.sym == SDLK_PAUSE) {
- /* specific case */
- v = 0;
- if (ev->type == SDL_KEYUP)
- v |= 0x80;
- kbd_put_keycode(0xe1);
- kbd_put_keycode(0x1d | v);
- kbd_put_keycode(0x45 | v);
- return;
- }
-
- /* XXX: not portable, but avoids complicated mappings */
- keycode = sdl_keyevent_to_keycode(ev);
-
- switch(keycode) {
- case 0x00:
- /* sent when leaving window: reset the modifiers state */
- reset_keys();
- return;
- case 0x2a: /* Left Shift */
- case 0x36: /* Right Shift */
- case 0x1d: /* Left CTRL */
- case 0x9d: /* Right CTRL */
- case 0x38: /* Left ALT */
- case 0xb8: /* Right ALT */
- if (ev->type == SDL_KEYUP)
- modifiers_state[keycode] = 0;
- else
- modifiers_state[keycode] = 1;
- break;
- case 0x45: /* num lock */
- case 0x3a: /* caps lock */
- /* SDL does not send the key up event, so we generate it */
- kbd_put_keycode(keycode);
- kbd_put_keycode(keycode | 0x80);
- return;
- }
- }
-
- /* now send the key code */
- if (keycode & 0x80)
- kbd_put_keycode(0xe0);
- if (ev->type == SDL_KEYUP)
- kbd_put_keycode(keycode | 0x80);
- else
- kbd_put_keycode(keycode & 0x7f);
-}
-
-static void sdl_update_caption(void)
-{
- char buf[1024];
- strcpy(buf, domain_name);
- if (!vm_running) {
- strcat(buf, " [Stopped]");
- }
- if (gui_grab) {
- strcat(buf, " - Press Ctrl-Alt to exit grab");
- }
- SDL_WM_SetCaption(buf, domain_name);
-}
-
-static void sdl_hide_cursor(void)
-{
- if (kbd_mouse_is_absolute()) {
- SDL_ShowCursor(1);
- SDL_SetCursor(sdl_cursor_hidden);
- } else {
- SDL_ShowCursor(0);
- }
-}
-
-static void sdl_show_cursor(void)
-{
- if (!kbd_mouse_is_absolute()) {
- SDL_ShowCursor(1);
- }
-}
-
-static void sdl_grab_start(void)
-{
- sdl_hide_cursor();
- SDL_WM_GrabInput(SDL_GRAB_ON);
- /* dummy read to avoid moving the mouse */
- SDL_GetRelativeMouseState(NULL, NULL);
- gui_grab = 1;
- sdl_update_caption();
-}
-
-static void sdl_grab_end(void)
-{
- SDL_WM_GrabInput(SDL_GRAB_OFF);
- sdl_show_cursor();
- SDL_ShowCursor(1);
- gui_grab = 0;
- sdl_update_caption();
-}
-
-static void sdl_send_mouse_event(void)
-{
- int dx, dy, dz, state, buttons;
- state = SDL_GetRelativeMouseState(&dx, &dy);
- buttons = 0;
- if (state & SDL_BUTTON(SDL_BUTTON_LEFT))
- buttons |= MOUSE_EVENT_LBUTTON;
- if (state & SDL_BUTTON(SDL_BUTTON_RIGHT))
- buttons |= MOUSE_EVENT_RBUTTON;
- if (state & SDL_BUTTON(SDL_BUTTON_MIDDLE))
- buttons |= MOUSE_EVENT_MBUTTON;
-
- if (kbd_mouse_is_absolute()) {
- if (!absolute_enabled) {
- sdl_hide_cursor();
- if (gui_grab) {
- sdl_grab_end();
- }
- absolute_enabled = 1;
- }
-
- SDL_GetMouseState(&dx, &dy);
- dx = dx * 0x7FFF / width;
- dy = dy * 0x7FFF / height;
- }
-
- /* XXX: test wheel */
- dz = 0;
-#ifdef SDL_BUTTON_WHEELUP
- if (state & SDL_BUTTON(SDL_BUTTON_WHEELUP))
- dz--;
- if (state & SDL_BUTTON(SDL_BUTTON_WHEELDOWN))
- dz++;
-#endif
- kbd_mouse_event(dx, dy, dz, buttons);
-}
-
-static void toggle_full_screen(DisplayState *ds)
-{
- gui_fullscreen = !gui_fullscreen;
- sdl_resize(ds, screen->w, screen->h);
- if (gui_fullscreen) {
- gui_saved_grab = gui_grab;
- sdl_grab_start();
- } else {
- if (!gui_saved_grab)
- sdl_grab_end();
- }
- vga_invalidate_display();
- vga_update_display();
-}
-
-static void sdl_refresh(DisplayState *ds)
-{
- SDL_Event ev1, *ev = &ev1;
- int mod_state;
-
- if (last_vm_running != vm_running) {
- last_vm_running = vm_running;
- sdl_update_caption();
- }
-
- if (is_active_console(vga_console))
- vga_update_display();
-
- while (SDL_PollEvent(ev)) {
- switch (ev->type) {
- case SDL_VIDEOEXPOSE:
- sdl_update(ds, 0, 0, screen->w, screen->h);
- break;
- case SDL_KEYDOWN:
- case SDL_KEYUP:
- if (ev->type == SDL_KEYDOWN) {
- mod_state = (SDL_GetModState() & gui_grab_code) ==
- gui_grab_code;
- gui_key_modifier_pressed = mod_state;
- if (gui_key_modifier_pressed) {
- int keycode;
- keycode = sdl_keyevent_to_keycode(&ev->key);
- switch(keycode) {
- case 0x21: /* 'f' key on US keyboard */
- toggle_full_screen(ds);
- gui_keysym = 1;
- break;
- case 0x02 ... 0x0a: /* '1' to '9' keys */
- console_select(keycode - 0x02);
- if (is_active_console(vga_console)) {
- /* tell the vga console to redisplay itself */
- vga_invalidate_display();
- } else {
- /* display grab if going to a text console */
- if (gui_grab)
- sdl_grab_end();
- }
- gui_keysym = 1;
- break;
- default:
- break;
- }
- } else if (!is_active_console(vga_console)) {
- int keysym;
- keysym = 0;
- if (ev->key.keysym.mod & (KMOD_LCTRL | KMOD_RCTRL)) {
- switch(ev->key.keysym.sym) {
- case SDLK_UP: keysym = QEMU_KEY_CTRL_UP; break;
- case SDLK_DOWN: keysym = QEMU_KEY_CTRL_DOWN; break;
- case SDLK_LEFT: keysym = QEMU_KEY_CTRL_LEFT; break;
- case SDLK_RIGHT: keysym = QEMU_KEY_CTRL_RIGHT; break;
- case SDLK_HOME: keysym = QEMU_KEY_CTRL_HOME; break;
- case SDLK_END: keysym = QEMU_KEY_CTRL_END; break;
- case SDLK_PAGEUP: keysym = QEMU_KEY_CTRL_PAGEUP; break;
- case SDLK_PAGEDOWN: keysym = QEMU_KEY_CTRL_PAGEDOWN; break;
- default: break;
- }
- } else {
- switch(ev->key.keysym.sym) {
- case SDLK_UP: keysym = QEMU_KEY_UP; break;
- case SDLK_DOWN: keysym = QEMU_KEY_DOWN; break;
- case SDLK_LEFT: keysym = QEMU_KEY_LEFT; break;
- case SDLK_RIGHT: keysym = QEMU_KEY_RIGHT; break;
- case SDLK_HOME: keysym = QEMU_KEY_HOME; break;
- case SDLK_END: keysym = QEMU_KEY_END; break;
- case SDLK_PAGEUP: keysym = QEMU_KEY_PAGEUP; break;
- case SDLK_PAGEDOWN: keysym = QEMU_KEY_PAGEDOWN; break;
- case SDLK_BACKSPACE: keysym = QEMU_KEY_BACKSPACE; break; case SDLK_DELETE: keysym = QEMU_KEY_DELETE; break;
- default: break;
- }
- }
- if (keysym) {
- kbd_put_keysym(keysym);
- } else if (ev->key.keysym.unicode != 0) {
- kbd_put_keysym(ev->key.keysym.unicode);
- }
- }
- } else if (ev->type == SDL_KEYUP) {
- mod_state = (ev->key.keysym.mod & gui_grab_code);
- if (!mod_state) {
- if (gui_key_modifier_pressed) {
- gui_key_modifier_pressed = 0;
- if (gui_keysym == 0) {
- /* exit/enter grab if pressing Ctrl-Alt */
- if (!gui_grab)
- sdl_grab_start();
- else
- sdl_grab_end();
- /* SDL does not send back all the
- modifiers key, so we must correct it */
- reset_keys();
- break;
- }
- gui_keysym = 0;
- }
- }
- }
- if (is_active_console(vga_console))
- sdl_process_key(&ev->key);
- break;
- case SDL_QUIT:
- qemu_system_shutdown_request();
- break;
- case SDL_MOUSEMOTION:
- if (gui_grab) {
- sdl_send_mouse_event();
- }
- break;
- case SDL_MOUSEBUTTONDOWN:
- case SDL_MOUSEBUTTONUP:
- {
- SDL_MouseButtonEvent *bev = &ev->button;
- if (!gui_grab) {
- if (ev->type == SDL_MOUSEBUTTONDOWN &&
- (bev->state & SDL_BUTTON_LMASK)) {
- /* start grabbing all events */
- sdl_grab_start();
- }
- } else {
- sdl_send_mouse_event();
- }
- }
- break;
- case SDL_ACTIVEEVENT:
- if (gui_grab && (ev->active.gain & SDL_ACTIVEEVENTMASK) == 0 &&
- !gui_fullscreen_initial_grab) {
- sdl_grab_end();
- }
- break;
- default:
- break;
- }
- }
-}
-
-static void sdl_cleanup(void)
-{
- SDL_Quit();
-}
-
-void sdl_display_init(DisplayState *ds, int full_screen)
-{
- int flags;
- uint8_t data = 0;
-
- if(keyboard_layout)
- kbd_layout=init_keyboard_layout(keyboard_layout);
-
- flags = SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE;
- if (SDL_Init (flags)) {
- fprintf(stderr, "Could not initialize SDL - exiting\n");
- exit(1);
- }
-#ifndef _WIN32
- /* NOTE: we still want Ctrl-C to work, so we undo the SDL redirections */
- signal(SIGINT, SIG_DFL);
- signal(SIGQUIT, SIG_DFL);
-#endif
-
- ds->dpy_update = sdl_update;
- ds->dpy_resize = sdl_resize;
- ds->dpy_refresh = sdl_refresh;
-
- sdl_resize(ds, 640, 400);
- sdl_update_caption();
- if(repeat_key)
- SDL_EnableKeyRepeat(250, 50);
- SDL_EnableUNICODE(1);
- gui_grab = 0;
-
- sdl_cursor_hidden = SDL_CreateCursor(&data, &data, 8, 1, 0, 0);
- sdl_cursor_normal = SDL_GetCursor();
-
- atexit(sdl_cleanup);
- if (full_screen) {
- gui_fullscreen = 1;
- gui_fullscreen_initial_grab = 1;
- sdl_grab_start();
- }
-}
+++ /dev/null
-include config.mak
-override TARGET_ARCH=i386
-
-XEN_ROOT=../../..
-include $(XEN_ROOT)/tools/Rules.mk
-
-INSTALL_DIR := $(DESTDIR)/usr/$(LIBDIR)/xen/bin
-TARGET_PATH=$(SRC_PATH)/target-$(TARGET_ARCH)
-VPATH=$(SRC_PATH):$(TARGET_PATH):$(SRC_PATH)/hw:$(SRC_PATH)/audio
-DEFINES=-I. -I$(TARGET_PATH) -I$(SRC_PATH)
-DEFINES+= -I$(XEN_ROOT)/tools/libxc -I$(XEN_ROOT)/tools/xenstore
-ifdef CONFIG_USER_ONLY
-VPATH+=:$(SRC_PATH)/linux-user
-DEFINES+=-I$(SRC_PATH)/linux-user -I$(SRC_PATH)/linux-user/$(TARGET_ARCH)
-endif
-
-SSE2 := $(call test-gcc-flag,$(CC),-msse2)
-ifeq ($(SSE2),-msse2)
-CFLAGS += -DUSE_SSE2=1 -msse2
-endif
-
-CFLAGS += -g -fno-strict-aliasing $(LOCAL_CFLAGS)
-LDFLAGS = -g
-
-LIBS=
-HELPER_CFLAGS=$(CFLAGS)
-DYNGEN=../dyngen$(EXESUF)
-# user emulator name
-QEMU_USER=qemu-$(TARGET_ARCH)
-# system emulator name
-ifdef CONFIG_SOFTMMU
-ifeq ($(TARGET_ARCH), i386)
-QEMU_SYSTEM=qemu$(EXESUF)
-else
-QEMU_SYSTEM=qemu-system-$(TARGET_ARCH)$(EXESUF)
-endif
-else
-QEMU_SYSTEM=qemu-fast
-endif
-
-QEMU_SYSTEM=qemu-dm
-PROGS=$(QEMU_SYSTEM)
-
-ifdef CONFIG_USER_ONLY
-PROGS=$(QEMU_USER)
-else
-ifeq ($(TARGET_ARCH), i386)
-
-ifeq ($(ARCH), i386)
-PROGS+=$(QEMU_SYSTEM)
-ifndef CONFIG_SOFTMMU
-CONFIG_STATIC=y
-endif
-else
-# the system emulator using soft mmu is portable
-ifdef CONFIG_SOFTMMU
-PROGS+=$(QEMU_SYSTEM)
-endif
-endif # ARCH != i386
-
-endif # TARGET_ARCH = i386
-
-ifeq ($(TARGET_ARCH), ppc)
-
-ifeq ($(ARCH), ppc)
-PROGS+=$(QEMU_SYSTEM)
-endif
-
-ifeq ($(ARCH), i386)
-ifdef CONFIG_SOFTMMU
-PROGS+=$(QEMU_SYSTEM)
-endif
-endif # ARCH = i386
-
-ifeq ($(ARCH), amd64)
-ifdef CONFIG_SOFTMMU
-PROGS+=$(QEMU_SYSTEM)
-endif
-endif # ARCH = amd64
-
-endif # TARGET_ARCH = ppc
-
-ifeq ($(TARGET_ARCH), sparc)
-
-ifeq ($(ARCH), ppc)
-PROGS+=$(QEMU_SYSTEM)
-endif
-
-ifeq ($(ARCH), i386)
-ifdef CONFIG_SOFTMMU
-PROGS+=$(QEMU_SYSTEM)
-endif
-endif # ARCH = i386
-
-ifeq ($(ARCH), amd64)
-ifdef CONFIG_SOFTMMU
-PROGS+=$(QEMU_SYSTEM)
-endif
-endif # ARCH = amd64
-
-endif # TARGET_ARCH = sparc
-endif # !CONFIG_USER_ONLY
-
-ifdef CONFIG_STATIC
-LDFLAGS+=-static
-endif
-
-ifeq ($(ARCH),i386)
-OP_CFLAGS=$(CFLAGS) -mpreferred-stack-boundary=2
-ifeq ($(HAVE_GCC3_OPTIONS),yes)
-OP_CFLAGS+= -falign-functions=0 -fno-gcse
-else
-OP_CFLAGS+= -malign-functions=0
-endif
-
-ifdef TARGET_GPROF
-USE_I386_LD=y
-endif
-ifdef CONFIG_STATIC
-USE_I386_LD=y
-endif
-ifdef USE_I386_LD
-LDFLAGS+=-Wl,-T,$(SRC_PATH)/i386.ld
-else
-# WARNING: this LDFLAGS is _very_ tricky : qemu is an ELF shared object
-# that the kernel ELF loader considers as an executable. I think this
-# is the simplest way to make it self virtualizable!
-LDFLAGS+=-Wl,-shared
-endif
-endif
-
-ifeq ($(ARCH),amd64)
-OP_CFLAGS=$(CFLAGS) -falign-functions=0
-LDFLAGS+=-Wl,-T,$(SRC_PATH)/amd64.ld
-endif
-
-ifeq ($(ARCH),ppc)
-CFLAGS+= -D__powerpc__
-OP_CFLAGS=$(CFLAGS)
-LDFLAGS+=-Wl,-T,$(SRC_PATH)/ppc.ld
-endif
-
-ifeq ($(ARCH),s390)
-OP_CFLAGS=$(CFLAGS)
-LDFLAGS+=-Wl,-T,$(SRC_PATH)/s390.ld
-endif
-
-ifeq ($(ARCH),sparc)
-CFLAGS+=-m32 -ffixed-g1 -ffixed-g2 -ffixed-g3 -ffixed-g6
-LDFLAGS+=-m32
-OP_CFLAGS=$(CFLAGS) -fno-delayed-branch -ffixed-i0
-HELPER_CFLAGS=$(CFLAGS) -ffixed-i0 -mflat
-# -static is used to avoid g1/g3 usage by the dynamic linker
-LDFLAGS+=-Wl,-T,$(SRC_PATH)/sparc.ld -static
-endif
-
-ifeq ($(ARCH),sparc64)
-CFLAGS+=-m64 -ffixed-g1 -ffixed-g2 -ffixed-g3 -ffixed-g6
-LDFLAGS+=-m64
-OP_CFLAGS=$(CFLAGS) -fno-delayed-branch -ffixed-i0
-endif
-
-ifeq ($(ARCH),alpha)
-# -msmall-data is not used because we want two-instruction relocations
-# for the constant constructions
-OP_CFLAGS=-Wall -O2 -g
-# Ensure there's only a single GP
-CFLAGS += -msmall-data
-LDFLAGS+=-Wl,-T,$(SRC_PATH)/alpha.ld
-endif
-
-ifeq ($(ARCH),ia64)
-OP_CFLAGS=$(CFLAGS)
-endif
-
-ifeq ($(ARCH),arm)
-OP_CFLAGS=$(CFLAGS) -mno-sched-prolog
-LDFLAGS+=-Wl,-T,$(SRC_PATH)/arm.ld
-endif
-
-ifeq ($(ARCH),m68k)
-OP_CFLAGS=$(CFLAGS) -fomit-frame-pointer
-LDFLAGS+=-Wl,-T,m68k.ld
-endif
-
-ifeq ($(HAVE_GCC3_OPTIONS),yes)
-# very important to generate a return at the end of every operation
-OP_CFLAGS+=-fno-reorder-blocks -fno-optimize-sibling-calls
-endif
-
-ifeq ($(CONFIG_DARWIN),yes)
-OP_CFLAGS+= -mdynamic-no-pic
-endif
-
-#########################################################
-
-DEFINES+=-D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE
-LIBS+=-lm -L../../libxc -lxenctrl -lxenguest -L../../xenstore -lxenstore
-ifndef CONFIG_USER_ONLY
-LIBS+=-lz
-endif
-ifdef CONFIG_WIN32
-LIBS+=-lwinmm -lws2_32 -liphlpapi
-endif
-
-# profiling code
-ifdef TARGET_GPROF
-LDFLAGS+=-p
-main.o: CFLAGS+=-p
-endif
-
-OBJS= elfload.o main.o syscall.o mmap.o signal.o path.o osdep.o thunk.o
-ifeq ($(TARGET_ARCH), i386)
-OBJS+= vm86.o
-endif
-ifeq ($(TARGET_ARCH), arm)
-OBJS+=nwfpe/softfloat.o nwfpe/fpa11.o nwfpe/fpa11_cpdo.o \
-nwfpe/fpa11_cpdt.o nwfpe/fpa11_cprt.o nwfpe/fpopcode.o nwfpe/single_cpdo.o \
- nwfpe/double_cpdo.o nwfpe/extended_cpdo.o
-endif
-SRCS:= $(OBJS:.o=.c)
-OBJS+= libqemu.a
-
-# cpu emulator library
-LIBOBJS=
-
-ifeq ($(TARGET_ARCH), i386)
-LIBOBJS+= helper2.o
-ifeq ($(ARCH), i386)
-LIBOBJS+=translate-copy.o
-endif
-endif
-
-ifeq ($(TARGET_ARCH), ppc)
-LIBOBJS+= op_helper.o helper.o
-endif
-
-ifeq ($(TARGET_ARCH), sparc)
-LIBOBJS+= op_helper.o helper.o
-endif
-
-all: $(PROGS)
-
-$(QEMU_USER): $(OBJS)
- $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LIBS)
-ifeq ($(ARCH),alpha)
-# Mark as 32 bit binary, i. e. it will be mapped into the low 31 bit of
-# the address space (31 bit so sign extending doesn't matter)
- echo -ne '\001\000\000\000' | dd of=qemu bs=1 seek=48 count=4 conv=notrunc
-endif
-
-# must use static linking to avoid leaving stuff in virtual address space
-VL_OBJS=vl.o exec.o monitor.o osdep.o block.o readline.o pci.o console.o
-VL_OBJS+=block-cow.o block-qcow.o block-vmdk.o block-cloop.o aes.o
-#VL_OBJS+= block-cloop.o
-
-SOUND_HW = sb16.o
-AUDIODRV = audio.o noaudio.o wavaudio.o
-ifdef CONFIG_SDL
-AUDIODRV += sdlaudio.o
-endif
-ifdef CONFIG_OSS
-AUDIODRV += ossaudio.o
-endif
-
-pc.o: DEFINES := -DUSE_SB16 $(DEFINES)
-
-ifdef CONFIG_ADLIB
-SOUND_HW += fmopl.o adlib.o
-endif
-
-ifdef CONFIG_FMOD
-AUDIODRV += fmodaudio.o
-audio.o fmodaudio.o: DEFINES := -I$(CONFIG_FMOD_INC) $(DEFINES)
-LIBS += $(CONFIG_FMOD_LIB)
-endif
-
-# USB layer
-VL_OBJS+= usb.o usb-hub.o usb-uhci.o usb-linux.o usb-hid.o
-
-# Hardware support
-VL_OBJS+= ide.o ne2000.o pckbd.o vga.o dma.o
-VL_OBJS+= fdc.o mc146818rtc.o serial.o i8259_stub.o pc.o port-e9.o
-VL_OBJS+= cirrus_vga.o pcnet.o piix4acpi.o
-VL_OBJS+= $(SOUND_HW) $(AUDIODRV) mixeng.o
-
-ifeq ($(TARGET_ARCH), ppc)
-VL_OBJS+= ppc.o ide.o ne2000.o pckbd.o vga.o $(SOUND_HW) dma.o $(AUDIODRV)
-VL_OBJS+= mc146818rtc.o serial.o i8259.o i8254.o fdc.o m48t59.o
-VL_OBJS+= ppc_prep.o ppc_chrp.o cuda.o adb.o openpic.o mixeng.o
-endif
-ifeq ($(TARGET_ARCH), sparc)
-VL_OBJS+= sun4m.o tcx.o lance.o iommu.o sched.o m48t08.o magic-load.o timer.o
-endif
-ifdef CONFIG_GDBSTUB
-VL_OBJS+=gdbstub.o
-endif
-ifdef CONFIG_VNC
-VL_OBJS+=vnc.o
-endif
-ifdef CONFIG_SDL
-VL_OBJS+=sdl.o
-endif
-ifdef CONFIG_SLIRP
-DEFINES+=-I$(SRC_PATH)/slirp
-SLIRP_OBJS=cksum.o if.o ip_icmp.o ip_input.o ip_output.o \
-slirp.o mbuf.o misc.o sbuf.o socket.o tcp_input.o tcp_output.o \
-tcp_subr.o tcp_timer.o udp.o bootp.o debug.o tftp.o
-VL_OBJS+=$(addprefix slirp/, $(SLIRP_OBJS))
-endif
-
-VL_LDFLAGS=
-# specific flags are needed for non soft mmu emulator
-ifdef CONFIG_STATIC
-VL_LDFLAGS+=-static
-endif
-ifndef CONFIG_DARWIN
-ifndef CONFIG_WIN32
-VL_LIBS=-lutil
-endif
-endif
-
-$(QEMU_SYSTEM): $(VL_OBJS) libqemu.a
- $(CC) $(CFLAGS) $(VL_LDFLAGS) -o $@ $^ $(LIBS) $(SDL_LIBS) $(VNC_LIBS) $(VL_LIBS) -lpthread
-
-vnc.o: vnc.c keyboard_rdesktop.c
- $(CC) $(CFLAGS) $(DEFINES) $(VNC_CFLAGS) -c -o $@ $<
-
-sdl.o: sdl.c keyboard_rdesktop.c
- $(CC) $(CFLAGS) $(DEFINES) $(SDL_CFLAGS) -c -o $@ $<
-
-sdlaudio.o: sdlaudio.c
- $(CC) $(CFLAGS) $(DEFINES) $(SDL_CFLAGS) -c -o $@ $<
-
-.PHONY: depend
-depend: $(SRCS)
- $(CC) -MM $(CFLAGS) $(DEFINES) $^ 1>.depend
-
-# libqemu
-
-libqemu.a: $(LIBOBJS)
- rm -f $@
- $(AR) rcs $@ $(LIBOBJS)
-
-translate.o: translate.c gen-op.h opc.h cpu.h
-
-translate-all.o: translate-all.c op.h opc.h cpu.h
-
-op.h: op.o $(DYNGEN)
- $(DYNGEN) -o $@ $<
-
-opc.h: op.o $(DYNGEN)
- $(DYNGEN) -c -o $@ $<
-
-gen-op.h: op.o $(DYNGEN)
- $(DYNGEN) -g -o $@ $<
-
-op.o: op.c
- $(CC) $(OP_CFLAGS) $(DEFINES) -c -o $@ $<
-
-helper.o: helper.c
- $(CC) $(HELPER_CFLAGS) $(DEFINES) -c -o $@ $<
-
-ifeq ($(TARGET_ARCH), i386)
-op.o: op.c opreg_template.h ops_template.h ops_template_mem.h ops_mem.h
-endif
-
-ifeq ($(TARGET_ARCH), arm)
-op.o: op.c op_template.h
-endif
-
-ifeq ($(TARGET_ARCH), sparc)
-op.o: op.c op_template.h op_mem.h
-endif
-
-ifeq ($(TARGET_ARCH), ppc)
-op.o: op.c op_template.h op_mem.h
-op_helper.o: op_helper_mem.h
-endif
-
-mixeng.o: mixeng.c mixeng.h mixeng_template.h
-
-%.o: %.c
- $(CC) $(CFLAGS) $(DEFINES) -c -o $@ $<
-
-%.o: %.S
- $(CC) $(DEFINES) -c -o $@ $<
-
-.PHONY: clean
-clean:
- rm -rf *.o *.a *~ $(PROGS) gen-op.h opc.h op.h nwfpe slirp
- rm -rf config.mak config.h
-
-.PHONY: distclean
-distclean: clean
-
-.PHONY: install
-install: all
- if [ ! -d $(INSTALL_DIR) ];then mkdir -p $(INSTALL_DIR);fi
- if [ ! -d $(DESTDIR)$(configdir) ];then mkdir -p $(DESTDIR)$(configdir);fi
- install -m 755 -s $(PROGS) "$(INSTALL_DIR)"
- install -m 755 qemu-dm.debug "$(INSTALL_DIR)"
- install -m 755 qemu-ifup "$(DESTDIR)$(configdir)"
-ifneq ($(wildcard .depend),)
-include .depend
-endif
+++ /dev/null
-/*
- * i386 helpers (without register variable usage)
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/*
- * Main cpu loop for handling I/O requests coming from a virtual machine
- *
- * Copyright © 2004, Intel Corporation.
- * Copyright © 2005, International Business Machines Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU Lesser General Public License,
- * version 2.1, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA.
- */
-#include <stdarg.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <inttypes.h>
-#include <signal.h>
-#include <assert.h>
-
-#include <limits.h>
-#include <fcntl.h>
-
-#include <xenctrl.h>
-#include <xen/hvm/ioreq.h>
-
-#include "cpu.h"
-#include "exec-all.h"
-#include "vl.h"
-
-extern int domid;
-extern int vcpus;
-
-void *shared_vram;
-
-shared_iopage_t *shared_page = NULL;
-extern int reset_requested;
-
-CPUX86State *cpu_86_init(void)
-{
- CPUX86State *env;
- static int inited;
-
- cpu_exec_init();
-
- env = malloc(sizeof(CPUX86State));
- if (!env)
- return NULL;
- memset(env, 0, sizeof(CPUX86State));
- /* init various static tables */
- if (!inited) {
- inited = 1;
- }
- cpu_single_env = env;
- cpu_reset(env);
- return env;
-}
-
-/* NOTE: must be called outside the CPU execute loop */
-void cpu_reset(CPUX86State *env)
-{
-}
-
-void cpu_x86_close(CPUX86State *env)
-{
- free(env);
-}
-
-
-void cpu_dump_state(CPUState *env, FILE *f,
- int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
- int flags)
-{
-}
-
-/***********************************************************/
-/* x86 mmu */
-/* XXX: add PGE support */
-
-void cpu_x86_set_a20(CPUX86State *env, int a20_state)
-{
- a20_state = (a20_state != 0);
- if (a20_state != ((env->a20_mask >> 20) & 1)) {
-#if defined(DEBUG_MMU)
- printf("A20 update: a20=%d\n", a20_state);
-#endif
- env->a20_mask = 0xffefffff | (a20_state << 20);
- }
-}
-
-target_ulong cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
-{
- return addr;
-}
-
-//the evtchn fd for polling
-int xce_handle = -1;
-
-//which vcpu we are serving
-int send_vcpu = 0;
-
-//some functions to handle the io req packet
-void sp_info()
-{
- ioreq_t *req;
- int i;
-
- for ( i = 0; i < vcpus; i++ ) {
- req = &(shared_page->vcpu_iodata[i].vp_ioreq);
- term_printf("vcpu %d: event port %d\n",
- i, shared_page->vcpu_iodata[i].vp_eport);
- term_printf(" req state: %x, pvalid: %x, addr: %"PRIx64", "
- "data: %"PRIx64", count: %"PRIx64", size: %"PRIx64"\n",
- req->state, req->pdata_valid, req->addr,
- req->u.data, req->count, req->size);
- term_printf(" IO totally occurred on this vcpu: %"PRIx64"\n",
- req->io_count);
- }
-}
-
-//get the ioreq packets from share mem
-static ioreq_t* __cpu_get_ioreq(int vcpu)
-{
- ioreq_t *req;
-
- req = &(shared_page->vcpu_iodata[vcpu].vp_ioreq);
-
- if ( req->state == STATE_IOREQ_READY )
- return req;
-
- fprintf(logfile, "False I/O request ... in-service already: "
- "%x, pvalid: %x, port: %"PRIx64", "
- "data: %"PRIx64", count: %"PRIx64", size: %"PRIx64"\n",
- req->state, req->pdata_valid, req->addr,
- req->u.data, req->count, req->size);
- return NULL;
-}
-
-//use poll to get the port notification
-//ioreq_vec--out,the
-//retval--the number of ioreq packet
-static ioreq_t* cpu_get_ioreq(void)
-{
- int i;
- evtchn_port_t port;
-
- if ( (port = xc_evtchn_pending(xce_handle)) != -1 ) {
- for ( i = 0; i < vcpus; i++ )
- if ( shared_page->vcpu_iodata[i].dm_eport == port )
- break;
-
- if ( i == vcpus ) {
- fprintf(logfile, "Fatal error while trying to get io event!\n");
- exit(1);
- }
-
- xc_evtchn_unmask(xce_handle, port);
-
- //get the io packet from shared memory
- send_vcpu = i;
- return __cpu_get_ioreq(i);
- }
-
- //read error or read nothing
- return NULL;
-}
-
-unsigned long do_inp(CPUState *env, unsigned long addr, unsigned long size)
-{
- switch(size) {
- case 1:
- return cpu_inb(env, addr);
- case 2:
- return cpu_inw(env, addr);
- case 4:
- return cpu_inl(env, addr);
- default:
- fprintf(logfile, "inp: bad size: %lx %lx\n", addr, size);
- exit(-1);
- }
-}
-
-void do_outp(CPUState *env, unsigned long addr,
- unsigned long size, unsigned long val)
-{
- switch(size) {
- case 1:
- return cpu_outb(env, addr, val);
- case 2:
- return cpu_outw(env, addr, val);
- case 4:
- return cpu_outl(env, addr, val);
- default:
- fprintf(logfile, "outp: bad size: %lx %lx\n", addr, size);
- exit(-1);
- }
-}
-
-extern void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf,
- int len, int is_write);
-
-static inline void read_physical(uint64_t addr, unsigned long size, void *val)
-{
- return cpu_physical_memory_rw((target_phys_addr_t)addr, val, size, 0);
-}
-
-static inline void write_physical(uint64_t addr, unsigned long size, void *val)
-{
- return cpu_physical_memory_rw((target_phys_addr_t)addr, val, size, 1);
-}
-
-void cpu_ioreq_pio(CPUState *env, ioreq_t *req)
-{
- int i, sign;
-
- sign = req->df ? -1 : 1;
-
- if (req->dir == IOREQ_READ) {
- if (!req->pdata_valid) {
- req->u.data = do_inp(env, req->addr, req->size);
- } else {
- unsigned long tmp;
-
- for (i = 0; i < req->count; i++) {
- tmp = do_inp(env, req->addr, req->size);
- write_physical((target_phys_addr_t) req->u.pdata
- + (sign * i * req->size),
- req->size, &tmp);
- }
- }
- } else if (req->dir == IOREQ_WRITE) {
- if (!req->pdata_valid) {
- do_outp(env, req->addr, req->size, req->u.data);
- } else {
- for (i = 0; i < req->count; i++) {
- unsigned long tmp;
-
- read_physical((target_phys_addr_t) req->u.pdata
- + (sign * i * req->size),
- req->size, &tmp);
- do_outp(env, req->addr, req->size, tmp);
- }
- }
- }
-}
-
-void cpu_ioreq_move(CPUState *env, ioreq_t *req)
-{
- int i, sign;
-
- sign = req->df ? -1 : 1;
-
- if (!req->pdata_valid) {
- if (req->dir == IOREQ_READ) {
- for (i = 0; i < req->count; i++) {
- read_physical(req->addr
- + (sign * i * req->size),
- req->size, &req->u.data);
- }
- } else if (req->dir == IOREQ_WRITE) {
- for (i = 0; i < req->count; i++) {
- write_physical(req->addr
- + (sign * i * req->size),
- req->size, &req->u.data);
- }
- }
- } else {
- unsigned long tmp;
-
- if (req->dir == IOREQ_READ) {
- for (i = 0; i < req->count; i++) {
- read_physical(req->addr
- + (sign * i * req->size),
- req->size, &tmp);
- write_physical((target_phys_addr_t )req->u.pdata
- + (sign * i * req->size),
- req->size, &tmp);
- }
- } else if (req->dir == IOREQ_WRITE) {
- for (i = 0; i < req->count; i++) {
- read_physical((target_phys_addr_t) req->u.pdata
- + (sign * i * req->size),
- req->size, &tmp);
- write_physical(req->addr
- + (sign * i * req->size),
- req->size, &tmp);
- }
- }
- }
-}
-
-void cpu_ioreq_and(CPUState *env, ioreq_t *req)
-{
- unsigned long tmp1, tmp2;
-
- if (req->pdata_valid != 0)
- hw_error("expected scalar value");
-
- read_physical(req->addr, req->size, &tmp1);
- if (req->dir == IOREQ_WRITE) {
- tmp2 = tmp1 & (unsigned long) req->u.data;
- write_physical(req->addr, req->size, &tmp2);
- }
- req->u.data = tmp1;
-}
-
-void cpu_ioreq_or(CPUState *env, ioreq_t *req)
-{
- unsigned long tmp1, tmp2;
-
- if (req->pdata_valid != 0)
- hw_error("expected scalar value");
-
- read_physical(req->addr, req->size, &tmp1);
- if (req->dir == IOREQ_WRITE) {
- tmp2 = tmp1 | (unsigned long) req->u.data;
- write_physical(req->addr, req->size, &tmp2);
- }
- req->u.data = tmp1;
-}
-
-void cpu_ioreq_xor(CPUState *env, ioreq_t *req)
-{
- unsigned long tmp1, tmp2;
-
- if (req->pdata_valid != 0)
- hw_error("expected scalar value");
-
- read_physical(req->addr, req->size, &tmp1);
- if (req->dir == IOREQ_WRITE) {
- tmp2 = tmp1 ^ (unsigned long) req->u.data;
- write_physical(req->addr, req->size, &tmp2);
- }
- req->u.data = tmp1;
-}
-
-void cpu_handle_ioreq(CPUState *env)
-{
- ioreq_t *req = cpu_get_ioreq();
-
- if (req) {
- req->state = STATE_IOREQ_INPROCESS;
-
- if ((!req->pdata_valid) && (req->dir == IOREQ_WRITE)) {
- if (req->size != 4)
- req->u.data &= (1UL << (8 * req->size))-1;
- }
-
- switch (req->type) {
- case IOREQ_TYPE_PIO:
- cpu_ioreq_pio(env, req);
- break;
- case IOREQ_TYPE_COPY:
- cpu_ioreq_move(env, req);
- break;
- case IOREQ_TYPE_AND:
- cpu_ioreq_and(env, req);
- break;
- case IOREQ_TYPE_OR:
- cpu_ioreq_or(env, req);
- break;
- case IOREQ_TYPE_XOR:
- cpu_ioreq_xor(env, req);
- break;
- default:
- hw_error("Invalid ioreq type 0x%x\n", req->type);
- }
-
- /* No state change if state = STATE_IORESP_HOOK */
- if (req->state == STATE_IOREQ_INPROCESS)
- req->state = STATE_IORESP_READY;
- env->send_event = 1;
- }
-}
-
-int xc_handle;
-
-void
-destroy_hvm_domain(void)
-{
- int xcHandle;
- int sts;
-
- xcHandle = xc_interface_open();
- if (xcHandle < 0)
- fprintf(logfile, "Cannot acquire xenctrl handle\n");
- else {
- sts = xc_domain_shutdown(xcHandle, domid, SHUTDOWN_poweroff);
- if (sts != 0)
- fprintf(logfile, "? xc_domain_shutdown failed to issue poweroff, sts %d, errno %d\n", sts, errno);
- else
- fprintf(logfile, "Issued domain %d poweroff\n", domid);
- xc_interface_close(xcHandle);
- }
-}
-
-fd_set wakeup_rfds;
-int highest_fds;
-int main_loop(void)
-{
- fd_set rfds;
- struct timeval tv;
- extern CPUState *global_env;
- extern int vm_running;
- extern int shutdown_requested;
- CPUState *env = global_env;
- int retval;
- int evtchn_fd = xc_evtchn_fd(xce_handle);
- extern void main_loop_wait(int);
-
- /* Watch stdin (fd 0) to see when it has input. */
- FD_ZERO(&wakeup_rfds);
- FD_SET(evtchn_fd, &wakeup_rfds);
- highest_fds = evtchn_fd;
- env->send_event = 0;
-
- while (1) {
- if (vm_running) {
- if (shutdown_requested) {
- break;
- }
- if (reset_requested){
- qemu_system_reset();
- reset_requested = 0;
- }
- }
-
- /* Wait up to 10 msec. */
- tv.tv_sec = 0;
- tv.tv_usec = 10000;
-
- retval = select(highest_fds+1, &wakeup_rfds, NULL, NULL, &tv);
- if (retval == -1) {
- fprintf(logfile, "select returned error %d\n", errno);
- return 0;
- }
- rfds = wakeup_rfds;
- FD_ZERO(&wakeup_rfds);
- FD_SET(evtchn_fd, &wakeup_rfds);
-
- tun_receive_handler(&rfds);
- if ( FD_ISSET(evtchn_fd, &rfds) ) {
- cpu_handle_ioreq(env);
- }
- main_loop_wait(0);
-
- if (env->send_event) {
- env->send_event = 0;
- (void)xc_evtchn_notify(xce_handle,
- shared_page->vcpu_iodata[send_vcpu].dm_eport);
- }
- }
- destroy_hvm_domain();
- return 0;
-}
-
-static void qemu_hvm_reset(void *unused)
-{
- int xcHandle;
- int sts;
-
- /* pause domain first, to avoid repeated reboot request*/
- xc_domain_pause(xc_handle, domid);
-
- xcHandle = xc_interface_open();
- if (xcHandle < 0)
- fprintf(logfile, "Cannot acquire xenctrl handle\n");
- else {
- sts = xc_domain_shutdown(xcHandle, domid, SHUTDOWN_reboot);
- if (sts != 0)
- fprintf(logfile, "? xc_domain_shutdown failed to issue reboot, sts %d\n", sts);
- else
- fprintf(logfile, "Issued domain %d reboot\n", domid);
- xc_interface_close(xcHandle);
- }
-
-}
-
-CPUState * cpu_init()
-{
- CPUX86State *env;
- int i, rc;
-
- cpu_exec_init();
- qemu_register_reset(qemu_hvm_reset, NULL);
- env = malloc(sizeof(CPUX86State));
- if (!env)
- return NULL;
- memset(env, 0, sizeof(CPUX86State));
-
- cpu_single_env = env;
-
- if (xce_handle != -1)//the evtchn has been opened by another cpu object
- return NULL;
-
- xce_handle = xc_evtchn_open();
- if (xce_handle == -1) {
- fprintf(logfile, "open evtchn device error %d\n", errno);
- return NULL;
- }
-
- /* FIXME: how about if we overflow the page here? */
- for ( i = 0; i < vcpus; i++ ) {
- rc = xc_evtchn_bind_interdomain(xce_handle, domid,
- shared_page->vcpu_iodata[i].vp_eport);
- if ( rc == -1 ) {
- fprintf(logfile, "bind interdomain ioctl error %d\n", errno);
- return NULL;
- }
- shared_page->vcpu_iodata[i].dm_eport = rc;
- }
-
- return env;
-}
+++ /dev/null
-#!/bin/sh
-
-echo $* > /tmp/args
-echo $DISPLAY >> /tmp/args
-exec /usr/lib/xen/bin/qemu-dm $*
+++ /dev/null
-#!/bin/sh
-
-#. /etc/rc.d/init.d/functions
-#ulimit -c unlimited
-
-echo 'config qemu network with xen bridge for '
-echo $*
-
-ifconfig $1 0.0.0.0 up
-brctl addif $2 $1
+++ /dev/null
-/*
- * Generic thunking code to convert data between host and target CPU
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdarg.h>
-
-#include "qemu.h"
-#include "thunk.h"
-
-//#define DEBUG
-
-#define MAX_STRUCTS 128
-
-/* XXX: make it dynamic */
-StructEntry struct_entries[MAX_STRUCTS];
-
-static inline const argtype *thunk_type_next(const argtype *type_ptr)
-{
- int type;
-
- type = *type_ptr++;
- switch(type) {
- case TYPE_CHAR:
- case TYPE_SHORT:
- case TYPE_INT:
- case TYPE_LONGLONG:
- case TYPE_ULONGLONG:
- case TYPE_LONG:
- case TYPE_ULONG:
- case TYPE_PTRVOID:
- return type_ptr;
- case TYPE_PTR:
- return thunk_type_next(type_ptr);
- case TYPE_ARRAY:
- return thunk_type_next(type_ptr + 1);
- case TYPE_STRUCT:
- return type_ptr + 1;
- default:
- return NULL;
- }
-}
-
-void thunk_register_struct(int id, const char *name, const argtype *types)
-{
- const argtype *type_ptr;
- StructEntry *se;
- int nb_fields, offset, max_align, align, size, i, j;
-
- se = struct_entries + id;
-
- /* first we count the number of fields */
- type_ptr = types;
- nb_fields = 0;
- while (*type_ptr != TYPE_NULL) {
- type_ptr = thunk_type_next(type_ptr);
- nb_fields++;
- }
- se->field_types = types;
- se->nb_fields = nb_fields;
- se->name = name;
-#ifdef DEBUG
- printf("struct %s: id=%d nb_fields=%d\n",
- se->name, id, se->nb_fields);
-#endif
- /* now we can alloc the data */
-
- for(i = 0;i < 2; i++) {
- offset = 0;
- max_align = 1;
- se->field_offsets[i] = malloc(nb_fields * sizeof(int));
- type_ptr = se->field_types;
- for(j = 0;j < nb_fields; j++) {
- size = thunk_type_size(type_ptr, i);
- align = thunk_type_align(type_ptr, i);
- offset = (offset + align - 1) & ~(align - 1);
- se->field_offsets[i][j] = offset;
- offset += size;
- if (align > max_align)
- max_align = align;
- type_ptr = thunk_type_next(type_ptr);
- }
- offset = (offset + max_align - 1) & ~(max_align - 1);
- se->size[i] = offset;
- se->align[i] = max_align;
-#ifdef DEBUG
- printf("%s: size=%d align=%d\n",
- i == THUNK_HOST ? "host" : "target", offset, max_align);
-#endif
- }
-}
-
-void thunk_register_struct_direct(int id, const char *name, StructEntry *se1)
-{
- StructEntry *se;
- se = struct_entries + id;
- *se = *se1;
- se->name = name;
-}
-
-
-/* now we can define the main conversion functions */
-const argtype *thunk_convert(void *dst, const void *src,
- const argtype *type_ptr, int to_host)
-{
- int type;
-
- type = *type_ptr++;
- switch(type) {
- case TYPE_CHAR:
- *(uint8_t *)dst = *(uint8_t *)src;
- break;
- case TYPE_SHORT:
- *(uint16_t *)dst = tswap16(*(uint16_t *)src);
- break;
- case TYPE_INT:
- *(uint32_t *)dst = tswap32(*(uint32_t *)src);
- break;
- case TYPE_LONGLONG:
- case TYPE_ULONGLONG:
- *(uint64_t *)dst = tswap64(*(uint64_t *)src);
- break;
-#if HOST_LONG_BITS == 32 && TARGET_LONG_BITS == 32
- case TYPE_LONG:
- case TYPE_ULONG:
- case TYPE_PTRVOID:
- *(uint32_t *)dst = tswap32(*(uint32_t *)src);
- break;
-#elif HOST_LONG_BITS == 64 && TARGET_LONG_BITS == 32
- case TYPE_LONG:
- case TYPE_ULONG:
- case TYPE_PTRVOID:
- if (to_host) {
- *(uint64_t *)dst = tswap32(*(uint32_t *)src);
- } else {
- *(uint32_t *)dst = tswap32(*(uint64_t *)src & 0xffffffff);
- }
- break;
-#else
-#error unsupported conversion
-#endif
- case TYPE_ARRAY:
- {
- int array_length, i, dst_size, src_size;
- const uint8_t *s;
- uint8_t *d;
-
- array_length = *type_ptr++;
- dst_size = thunk_type_size(type_ptr, to_host);
- src_size = thunk_type_size(type_ptr, 1 - to_host);
- d = dst;
- s = src;
- for(i = 0;i < array_length; i++) {
- thunk_convert(d, s, type_ptr, to_host);
- d += dst_size;
- s += src_size;
- }
- type_ptr = thunk_type_next(type_ptr);
- }
- break;
- case TYPE_STRUCT:
- {
- int i;
- const StructEntry *se;
- const uint8_t *s;
- uint8_t *d;
- const argtype *field_types;
- const int *dst_offsets, *src_offsets;
-
- se = struct_entries + *type_ptr++;
- if (se->convert[0] != NULL) {
- /* specific conversion is needed */
- (*se->convert[to_host])(dst, src);
- } else {
- /* standard struct conversion */
- field_types = se->field_types;
- dst_offsets = se->field_offsets[to_host];
- src_offsets = se->field_offsets[1 - to_host];
- d = dst;
- s = src;
- for(i = 0;i < se->nb_fields; i++) {
- field_types = thunk_convert(d + dst_offsets[i],
- s + src_offsets[i],
- field_types, to_host);
- }
- }
- }
- break;
- default:
- fprintf(stderr, "Invalid type 0x%x\n", type);
- break;
- }
- return type_ptr;
-}
-
-/* from em86 */
-
-/* Utility function: Table-driven functions to translate bitmasks
- * between X86 and Alpha formats...
- */
-unsigned int target_to_host_bitmask(unsigned int x86_mask,
- bitmask_transtbl * trans_tbl)
-{
- bitmask_transtbl * btp;
- unsigned int alpha_mask = 0;
-
- for(btp = trans_tbl; btp->x86_mask && btp->alpha_mask; btp++) {
- if((x86_mask & btp->x86_mask) == btp->x86_bits) {
- alpha_mask |= btp->alpha_bits;
- }
- }
- return(alpha_mask);
-}
-
-unsigned int host_to_target_bitmask(unsigned int alpha_mask,
- bitmask_transtbl * trans_tbl)
-{
- bitmask_transtbl * btp;
- unsigned int x86_mask = 0;
-
- for(btp = trans_tbl; btp->x86_mask && btp->alpha_mask; btp++) {
- if((alpha_mask & btp->alpha_mask) == btp->alpha_bits) {
- x86_mask |= btp->x86_bits;
- }
- }
- return(x86_mask);
-}
+++ /dev/null
-/*
- * Generic thunking code to convert data between host and target CPU
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#ifndef THUNK_H
-#define THUNK_H
-
-#include <inttypes.h>
-#include "cpu.h"
-
-/* types enums definitions */
-
-typedef enum argtype {
- TYPE_NULL,
- TYPE_CHAR,
- TYPE_SHORT,
- TYPE_INT,
- TYPE_LONG,
- TYPE_ULONG,
- TYPE_PTRVOID, /* pointer on unknown data */
- TYPE_LONGLONG,
- TYPE_ULONGLONG,
- TYPE_PTR,
- TYPE_ARRAY,
- TYPE_STRUCT,
-} argtype;
-
-#define MK_PTR(type) TYPE_PTR, type
-#define MK_ARRAY(type, size) TYPE_ARRAY, size, type
-#define MK_STRUCT(id) TYPE_STRUCT, id
-
-#define THUNK_TARGET 0
-#define THUNK_HOST 1
-
-typedef struct {
- /* standard struct handling */
- const argtype *field_types;
- int nb_fields;
- int *field_offsets[2];
- /* special handling */
- void (*convert[2])(void *dst, const void *src);
- int size[2];
- int align[2];
- const char *name;
-} StructEntry;
-
-/* Translation table for bitmasks... */
-typedef struct bitmask_transtbl {
- unsigned int x86_mask;
- unsigned int x86_bits;
- unsigned int alpha_mask;
- unsigned int alpha_bits;
-} bitmask_transtbl;
-
-void thunk_register_struct(int id, const char *name, const argtype *types);
-void thunk_register_struct_direct(int id, const char *name, StructEntry *se1);
-const argtype *thunk_convert(void *dst, const void *src,
- const argtype *type_ptr, int to_host);
-#ifndef NO_THUNK_TYPE_SIZE
-
-extern StructEntry struct_entries[];
-
-static inline int thunk_type_size(const argtype *type_ptr, int is_host)
-{
- int type, size;
- const StructEntry *se;
-
- type = *type_ptr;
- switch(type) {
- case TYPE_CHAR:
- return 1;
- case TYPE_SHORT:
- return 2;
- case TYPE_INT:
- return 4;
- case TYPE_LONGLONG:
- case TYPE_ULONGLONG:
- return 8;
- case TYPE_LONG:
- case TYPE_ULONG:
- case TYPE_PTRVOID:
- case TYPE_PTR:
- if (is_host) {
- return HOST_LONG_SIZE;
- } else {
- return TARGET_LONG_SIZE;
- }
- break;
- case TYPE_ARRAY:
- size = type_ptr[1];
- return size * thunk_type_size(type_ptr + 2, is_host);
- case TYPE_STRUCT:
- se = struct_entries + type_ptr[1];
- return se->size[is_host];
- default:
- return -1;
- }
-}
-
-static inline int thunk_type_align(const argtype *type_ptr, int is_host)
-{
- int type;
- const StructEntry *se;
-
- type = *type_ptr;
- switch(type) {
- case TYPE_CHAR:
- return 1;
- case TYPE_SHORT:
- return 2;
- case TYPE_INT:
- return 4;
- case TYPE_LONGLONG:
- case TYPE_ULONGLONG:
- return 8;
- case TYPE_LONG:
- case TYPE_ULONG:
- case TYPE_PTRVOID:
- case TYPE_PTR:
- if (is_host) {
- return HOST_LONG_SIZE;
- } else {
- return TARGET_LONG_SIZE;
- }
- break;
- case TYPE_ARRAY:
- return thunk_type_align(type_ptr + 2, is_host);
- case TYPE_STRUCT:
- se = struct_entries + type_ptr[1];
- return se->align[is_host];
- default:
- return -1;
- }
-}
-
-#endif /* NO_THUNK_TYPE_SIZE */
-
-unsigned int target_to_host_bitmask(unsigned int x86_mask,
- bitmask_transtbl * trans_tbl);
-unsigned int host_to_target_bitmask(unsigned int alpha_mask,
- bitmask_transtbl * trans_tbl);
-
-#endif
+++ /dev/null
-/*
- * Linux host USB redirector
- *
- * Copyright (c) 2005 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "vl.h"
-
-#if defined(__linux__)
-#include <dirent.h>
-#include <sys/ioctl.h>
-#define __user /* new versions of usbdevice_fs.h use this private attribute */
-#include <linux/usbdevice_fs.h>
-#include <linux/version.h>
-
-/* We redefine it to avoid version problems */
-struct usb_ctrltransfer {
- uint8_t bRequestType;
- uint8_t bRequest;
- uint16_t wValue;
- uint16_t wIndex;
- uint16_t wLength;
- uint32_t timeout;
- void *data;
-};
-
-typedef int USBScanFunc(void *opaque, int bus_num, int addr, int class_id,
- int vendor_id, int product_id,
- const char *product_name, int speed);
-static int usb_host_find_device(int *pbus_num, int *paddr,
- const char *devname);
-
-//#define DEBUG
-
-#define USBDEVFS_PATH "/proc/bus/usb"
-
-typedef struct USBHostDevice {
- USBDevice dev;
- int fd;
-} USBHostDevice;
-
-static void usb_host_handle_reset(USBDevice *dev)
-{
-#if 0
- USBHostDevice *s = (USBHostDevice *)dev;
- /* USBDEVFS_RESET, but not the first time as it has already be
- done by the host OS */
- ioctl(s->fd, USBDEVFS_RESET);
-#endif
-}
-
-static int usb_host_handle_control(USBDevice *dev,
- int request,
- int value,
- int index,
- int length,
- uint8_t *data)
-{
- USBHostDevice *s = (USBHostDevice *)dev;
- struct usb_ctrltransfer ct;
- int ret;
-
- if (request == (DeviceOutRequest | USB_REQ_SET_ADDRESS)) {
- /* specific SET_ADDRESS support */
- dev->addr = value;
- return 0;
- } else {
- ct.bRequestType = request >> 8;
- ct.bRequest = request;
- ct.wValue = value;
- ct.wIndex = index;
- ct.wLength = length;
- ct.timeout = 50;
- ct.data = data;
- ret = ioctl(s->fd, USBDEVFS_CONTROL, &ct);
- if (ret < 0) {
- switch(errno) {
- case ETIMEDOUT:
- return USB_RET_NAK;
- default:
- return USB_RET_STALL;
- }
- } else {
- return ret;
- }
- }
-}
-
-static int usb_host_handle_data(USBDevice *dev, int pid,
- uint8_t devep,
- uint8_t *data, int len)
-{
- USBHostDevice *s = (USBHostDevice *)dev;
- struct usbdevfs_bulktransfer bt;
- int ret;
-
- /* XXX: optimize and handle all data types by looking at the
- config descriptor */
- if (pid == USB_TOKEN_IN)
- devep |= 0x80;
- bt.ep = devep;
- bt.len = len;
- bt.timeout = 50;
- bt.data = data;
- ret = ioctl(s->fd, USBDEVFS_BULK, &bt);
- if (ret < 0) {
- switch(errno) {
- case ETIMEDOUT:
- return USB_RET_NAK;
- case EPIPE:
- default:
-#ifdef DEBUG
- printf("handle_data: errno=%d\n", errno);
-#endif
- return USB_RET_STALL;
- }
- } else {
- return ret;
- }
-}
-
-/* XXX: exclude high speed devices or implement EHCI */
-USBDevice *usb_host_device_open(const char *devname)
-{
- int fd, interface, ret, i;
- USBHostDevice *dev;
- struct usbdevfs_connectinfo ci;
- uint8_t descr[1024];
- char buf[1024];
- int descr_len, dev_descr_len, config_descr_len, nb_interfaces;
- int bus_num, addr;
-
- if (usb_host_find_device(&bus_num, &addr, devname) < 0)
- return NULL;
-
- snprintf(buf, sizeof(buf), USBDEVFS_PATH "/%03d/%03d",
- bus_num, addr);
- fd = open(buf, O_RDWR);
- if (fd < 0) {
- perror(buf);
- return NULL;
- }
-
- /* read the config description */
- descr_len = read(fd, descr, sizeof(descr));
- if (descr_len <= 0) {
- perror("read descr");
- goto fail;
- }
-
- i = 0;
- dev_descr_len = descr[0];
- if (dev_descr_len > descr_len)
- goto fail;
- i += dev_descr_len;
- config_descr_len = descr[i];
- if (i + config_descr_len > descr_len)
- goto fail;
- nb_interfaces = descr[i + 4];
- if (nb_interfaces != 1) {
- /* NOTE: currently we grab only one interface */
- fprintf(stderr, "usb_host: only one interface supported\n");
- goto fail;
- }
-
-#ifdef USBDEVFS_DISCONNECT
- /* earlier Linux 2.4 do not support that */
- {
- struct usbdevfs_ioctl ctrl;
- ctrl.ioctl_code = USBDEVFS_DISCONNECT;
- ctrl.ifno = 0;
- ret = ioctl(fd, USBDEVFS_IOCTL, &ctrl);
- if (ret < 0 && errno != ENODATA) {
- perror("USBDEVFS_DISCONNECT");
- goto fail;
- }
- }
-#endif
-
- /* XXX: only grab if all interfaces are free */
- interface = 0;
- ret = ioctl(fd, USBDEVFS_CLAIMINTERFACE, &interface);
- if (ret < 0) {
- if (errno == EBUSY) {
- fprintf(stderr, "usb_host: device already grabbed\n");
- } else {
- perror("USBDEVFS_CLAIMINTERFACE");
- }
- fail:
- close(fd);
- return NULL;
- }
-
- ret = ioctl(fd, USBDEVFS_CONNECTINFO, &ci);
- if (ret < 0) {
- perror("USBDEVFS_CONNECTINFO");
- goto fail;
- }
-
-#ifdef DEBUG
- printf("host USB device %d.%d grabbed\n", bus_num, addr);
-#endif
-
- dev = qemu_mallocz(sizeof(USBHostDevice));
- if (!dev)
- goto fail;
- dev->fd = fd;
- if (ci.slow)
- dev->dev.speed = USB_SPEED_LOW;
- else
- dev->dev.speed = USB_SPEED_HIGH;
- dev->dev.handle_packet = usb_generic_handle_packet;
-
- dev->dev.handle_reset = usb_host_handle_reset;
- dev->dev.handle_control = usb_host_handle_control;
- dev->dev.handle_data = usb_host_handle_data;
- return (USBDevice *)dev;
-}
-
-static int get_tag_value(char *buf, int buf_size,
- const char *str, const char *tag,
- const char *stopchars)
-{
- const char *p;
- char *q;
- p = strstr(str, tag);
- if (!p)
- return -1;
- p += strlen(tag);
- while (isspace(*p))
- p++;
- q = buf;
- while (*p != '\0' && !strchr(stopchars, *p)) {
- if ((q - buf) < (buf_size - 1))
- *q++ = *p;
- p++;
- }
- *q = '\0';
- return q - buf;
-}
-
-static int usb_host_scan(void *opaque, USBScanFunc *func)
-{
- FILE *f;
- char line[1024];
- char buf[1024];
- int bus_num, addr, speed, device_count, class_id, product_id, vendor_id;
- int ret;
- char product_name[512];
-
- f = fopen(USBDEVFS_PATH "/devices", "r");
- if (!f) {
- term_printf("Could not open %s\n", USBDEVFS_PATH "/devices");
- return 0;
- }
- device_count = 0;
- bus_num = addr = speed = class_id = product_id = vendor_id = 0;
- ret = 0;
- for(;;) {
- if (fgets(line, sizeof(line), f) == NULL)
- break;
- if (strlen(line) > 0)
- line[strlen(line) - 1] = '\0';
- if (line[0] == 'T' && line[1] == ':') {
- if (device_count && (vendor_id || product_id)) {
- /* New device. Add the previously discovered device. */
- ret = func(opaque, bus_num, addr, class_id, vendor_id,
- product_id, product_name, speed);
- if (ret)
- goto the_end;
- }
- if (get_tag_value(buf, sizeof(buf), line, "Bus=", " ") < 0)
- goto fail;
- bus_num = atoi(buf);
- if (get_tag_value(buf, sizeof(buf), line, "Dev#=", " ") < 0)
- goto fail;
- addr = atoi(buf);
- if (get_tag_value(buf, sizeof(buf), line, "Spd=", " ") < 0)
- goto fail;
- if (!strcmp(buf, "480"))
- speed = USB_SPEED_HIGH;
- else if (!strcmp(buf, "1.5"))
- speed = USB_SPEED_LOW;
- else
- speed = USB_SPEED_FULL;
- product_name[0] = '\0';
- class_id = 0xff;
- device_count++;
- product_id = 0;
- vendor_id = 0;
- } else if (line[0] == 'P' && line[1] == ':') {
- if (get_tag_value(buf, sizeof(buf), line, "Vendor=", " ") < 0)
- goto fail;
- vendor_id = strtoul(buf, NULL, 16);
- if (get_tag_value(buf, sizeof(buf), line, "ProdID=", " ") < 0)
- goto fail;
- product_id = strtoul(buf, NULL, 16);
- } else if (line[0] == 'S' && line[1] == ':') {
- if (get_tag_value(buf, sizeof(buf), line, "Product=", "") < 0)
- goto fail;
- pstrcpy(product_name, sizeof(product_name), buf);
- } else if (line[0] == 'D' && line[1] == ':') {
- if (get_tag_value(buf, sizeof(buf), line, "Cls=", " (") < 0)
- goto fail;
- class_id = strtoul(buf, NULL, 16);
- }
- fail: ;
- }
- if (device_count && (vendor_id || product_id)) {
- /* Add the last device. */
- ret = func(opaque, bus_num, addr, class_id, vendor_id,
- product_id, product_name, speed);
- }
- the_end:
- fclose(f);
- return ret;
-}
-
-typedef struct FindDeviceState {
- int vendor_id;
- int product_id;
- int bus_num;
- int addr;
-} FindDeviceState;
-
-static int usb_host_find_device_scan(void *opaque, int bus_num, int addr,
- int class_id,
- int vendor_id, int product_id,
- const char *product_name, int speed)
-{
- FindDeviceState *s = opaque;
- if (vendor_id == s->vendor_id &&
- product_id == s->product_id) {
- s->bus_num = bus_num;
- s->addr = addr;
- return 1;
- } else {
- return 0;
- }
-}
-
-/* the syntax is :
- 'bus.addr' (decimal numbers) or
- 'vendor_id:product_id' (hexa numbers) */
-static int usb_host_find_device(int *pbus_num, int *paddr,
- const char *devname)
-{
- const char *p;
- int ret;
- FindDeviceState fs;
-
- p = strchr(devname, '.');
- if (p) {
- *pbus_num = strtoul(devname, NULL, 0);
- *paddr = strtoul(p + 1, NULL, 0);
- return 0;
- }
- p = strchr(devname, ':');
- if (p) {
- fs.vendor_id = strtoul(devname, NULL, 16);
- fs.product_id = strtoul(p + 1, NULL, 16);
- ret = usb_host_scan(&fs, usb_host_find_device_scan);
- if (ret) {
- *pbus_num = fs.bus_num;
- *paddr = fs.addr;
- return 0;
- }
- }
- return -1;
-}
-
-/**********************/
-/* USB host device info */
-
-struct usb_class_info {
- int class;
- const char *class_name;
-};
-
-static const struct usb_class_info usb_class_info[] = {
- { USB_CLASS_AUDIO, "Audio"},
- { USB_CLASS_COMM, "Communication"},
- { USB_CLASS_HID, "HID"},
- { USB_CLASS_HUB, "Hub" },
- { USB_CLASS_PHYSICAL, "Physical" },
- { USB_CLASS_PRINTER, "Printer" },
- { USB_CLASS_MASS_STORAGE, "Storage" },
- { USB_CLASS_CDC_DATA, "Data" },
- { USB_CLASS_APP_SPEC, "Application Specific" },
- { USB_CLASS_VENDOR_SPEC, "Vendor Specific" },
- { USB_CLASS_STILL_IMAGE, "Still Image" },
- { USB_CLASS_CSCID, "Smart Card" },
- { USB_CLASS_CONTENT_SEC, "Content Security" },
- { -1, NULL }
-};
-
-static const char *usb_class_str(uint8_t class)
-{
- const struct usb_class_info *p;
- for(p = usb_class_info; p->class != -1; p++) {
- if (p->class == class)
- break;
- }
- return p->class_name;
-}
-
-void usb_info_device(int bus_num, int addr, int class_id,
- int vendor_id, int product_id,
- const char *product_name,
- int speed)
-{
- const char *class_str, *speed_str;
-
- switch(speed) {
- case USB_SPEED_LOW:
- speed_str = "1.5";
- break;
- case USB_SPEED_FULL:
- speed_str = "12";
- break;
- case USB_SPEED_HIGH:
- speed_str = "480";
- break;
- default:
- speed_str = "?";
- break;
- }
-
- term_printf(" Device %d.%d, speed %s Mb/s\n",
- bus_num, addr, speed_str);
- class_str = usb_class_str(class_id);
- if (class_str)
- term_printf(" %s:", class_str);
- else
- term_printf(" Class %02x:", class_id);
- term_printf(" USB device %04x:%04x", vendor_id, product_id);
- if (product_name[0] != '\0')
- term_printf(", %s", product_name);
- term_printf("\n");
-}
-
-static int usb_host_info_device(void *opaque, int bus_num, int addr,
- int class_id,
- int vendor_id, int product_id,
- const char *product_name,
- int speed)
-{
- usb_info_device(bus_num, addr, class_id, vendor_id, product_id,
- product_name, speed);
- return 0;
-}
-
-void usb_host_info(void)
-{
- usb_host_scan(NULL, usb_host_info_device);
-}
-
-#else
-
-void usb_host_info(void)
-{
- term_printf("USB host devices not supported\n");
-}
-
-/* XXX: modify configure to compile the right host driver */
-USBDevice *usb_host_device_open(const char *devname)
-{
- return NULL;
-}
-
-#endif
+++ /dev/null
-static uint8_t vgafont16[256 * 16] = {
-
- /* 0 0x00 '^@' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 1 0x01 '^A' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7e, /* 01111110 */
- 0x81, /* 10000001 */
- 0xa5, /* 10100101 */
- 0x81, /* 10000001 */
- 0x81, /* 10000001 */
- 0xbd, /* 10111101 */
- 0x99, /* 10011001 */
- 0x81, /* 10000001 */
- 0x81, /* 10000001 */
- 0x7e, /* 01111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 2 0x02 '^B' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7e, /* 01111110 */
- 0xff, /* 11111111 */
- 0xdb, /* 11011011 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xc3, /* 11000011 */
- 0xe7, /* 11100111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0x7e, /* 01111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 3 0x03 '^C' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x6c, /* 01101100 */
- 0xfe, /* 11111110 */
- 0xfe, /* 11111110 */
- 0xfe, /* 11111110 */
- 0xfe, /* 11111110 */
- 0x7c, /* 01111100 */
- 0x38, /* 00111000 */
- 0x10, /* 00010000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 4 0x04 '^D' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x10, /* 00010000 */
- 0x38, /* 00111000 */
- 0x7c, /* 01111100 */
- 0xfe, /* 11111110 */
- 0x7c, /* 01111100 */
- 0x38, /* 00111000 */
- 0x10, /* 00010000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 5 0x05 '^E' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x3c, /* 00111100 */
- 0x3c, /* 00111100 */
- 0xe7, /* 11100111 */
- 0xe7, /* 11100111 */
- 0xe7, /* 11100111 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x3c, /* 00111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 6 0x06 '^F' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x3c, /* 00111100 */
- 0x7e, /* 01111110 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0x7e, /* 01111110 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x3c, /* 00111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 7 0x07 '^G' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x3c, /* 00111100 */
- 0x3c, /* 00111100 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 8 0x08 '^H' */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xe7, /* 11100111 */
- 0xc3, /* 11000011 */
- 0xc3, /* 11000011 */
- 0xe7, /* 11100111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
-
- /* 9 0x09 '^I' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x3c, /* 00111100 */
- 0x66, /* 01100110 */
- 0x42, /* 01000010 */
- 0x42, /* 01000010 */
- 0x66, /* 01100110 */
- 0x3c, /* 00111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 10 0x0a '^J' */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xc3, /* 11000011 */
- 0x99, /* 10011001 */
- 0xbd, /* 10111101 */
- 0xbd, /* 10111101 */
- 0x99, /* 10011001 */
- 0xc3, /* 11000011 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
-
- /* 11 0x0b '^K' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x1e, /* 00011110 */
- 0x0e, /* 00001110 */
- 0x1a, /* 00011010 */
- 0x32, /* 00110010 */
- 0x78, /* 01111000 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0x78, /* 01111000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 12 0x0c '^L' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x3c, /* 00111100 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x3c, /* 00111100 */
- 0x18, /* 00011000 */
- 0x7e, /* 01111110 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 13 0x0d '^M' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x3f, /* 00111111 */
- 0x33, /* 00110011 */
- 0x3f, /* 00111111 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x70, /* 01110000 */
- 0xf0, /* 11110000 */
- 0xe0, /* 11100000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 14 0x0e '^N' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7f, /* 01111111 */
- 0x63, /* 01100011 */
- 0x7f, /* 01111111 */
- 0x63, /* 01100011 */
- 0x63, /* 01100011 */
- 0x63, /* 01100011 */
- 0x63, /* 01100011 */
- 0x67, /* 01100111 */
- 0xe7, /* 11100111 */
- 0xe6, /* 11100110 */
- 0xc0, /* 11000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 15 0x0f '^O' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0xdb, /* 11011011 */
- 0x3c, /* 00111100 */
- 0xe7, /* 11100111 */
- 0x3c, /* 00111100 */
- 0xdb, /* 11011011 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 16 0x10 '^P' */
- 0x00, /* 00000000 */
- 0x80, /* 10000000 */
- 0xc0, /* 11000000 */
- 0xe0, /* 11100000 */
- 0xf0, /* 11110000 */
- 0xf8, /* 11111000 */
- 0xfe, /* 11111110 */
- 0xf8, /* 11111000 */
- 0xf0, /* 11110000 */
- 0xe0, /* 11100000 */
- 0xc0, /* 11000000 */
- 0x80, /* 10000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 17 0x11 '^Q' */
- 0x00, /* 00000000 */
- 0x02, /* 00000010 */
- 0x06, /* 00000110 */
- 0x0e, /* 00001110 */
- 0x1e, /* 00011110 */
- 0x3e, /* 00111110 */
- 0xfe, /* 11111110 */
- 0x3e, /* 00111110 */
- 0x1e, /* 00011110 */
- 0x0e, /* 00001110 */
- 0x06, /* 00000110 */
- 0x02, /* 00000010 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 18 0x12 '^R' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x3c, /* 00111100 */
- 0x7e, /* 01111110 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x7e, /* 01111110 */
- 0x3c, /* 00111100 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 19 0x13 '^S' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x00, /* 00000000 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 20 0x14 '^T' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7f, /* 01111111 */
- 0xdb, /* 11011011 */
- 0xdb, /* 11011011 */
- 0xdb, /* 11011011 */
- 0x7b, /* 01111011 */
- 0x1b, /* 00011011 */
- 0x1b, /* 00011011 */
- 0x1b, /* 00011011 */
- 0x1b, /* 00011011 */
- 0x1b, /* 00011011 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 21 0x15 '^U' */
- 0x00, /* 00000000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0x60, /* 01100000 */
- 0x38, /* 00111000 */
- 0x6c, /* 01101100 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x6c, /* 01101100 */
- 0x38, /* 00111000 */
- 0x0c, /* 00001100 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 22 0x16 '^V' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xfe, /* 11111110 */
- 0xfe, /* 11111110 */
- 0xfe, /* 11111110 */
- 0xfe, /* 11111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 23 0x17 '^W' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x3c, /* 00111100 */
- 0x7e, /* 01111110 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x7e, /* 01111110 */
- 0x3c, /* 00111100 */
- 0x18, /* 00011000 */
- 0x7e, /* 01111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 24 0x18 '^X' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x3c, /* 00111100 */
- 0x7e, /* 01111110 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 25 0x19 '^Y' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x7e, /* 01111110 */
- 0x3c, /* 00111100 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 26 0x1a '^Z' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x0c, /* 00001100 */
- 0xfe, /* 11111110 */
- 0x0c, /* 00001100 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 27 0x1b '^[' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x30, /* 00110000 */
- 0x60, /* 01100000 */
- 0xfe, /* 11111110 */
- 0x60, /* 01100000 */
- 0x30, /* 00110000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 28 0x1c '^\' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xfe, /* 11111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 29 0x1d '^]' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x28, /* 00101000 */
- 0x6c, /* 01101100 */
- 0xfe, /* 11111110 */
- 0x6c, /* 01101100 */
- 0x28, /* 00101000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 30 0x1e '^^' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x10, /* 00010000 */
- 0x38, /* 00111000 */
- 0x38, /* 00111000 */
- 0x7c, /* 01111100 */
- 0x7c, /* 01111100 */
- 0xfe, /* 11111110 */
- 0xfe, /* 11111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 31 0x1f '^_' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xfe, /* 11111110 */
- 0xfe, /* 11111110 */
- 0x7c, /* 01111100 */
- 0x7c, /* 01111100 */
- 0x38, /* 00111000 */
- 0x38, /* 00111000 */
- 0x10, /* 00010000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 32 0x20 ' ' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 33 0x21 '!' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x3c, /* 00111100 */
- 0x3c, /* 00111100 */
- 0x3c, /* 00111100 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 34 0x22 '"' */
- 0x00, /* 00000000 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x24, /* 00100100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 35 0x23 '#' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x6c, /* 01101100 */
- 0x6c, /* 01101100 */
- 0xfe, /* 11111110 */
- 0x6c, /* 01101100 */
- 0x6c, /* 01101100 */
- 0x6c, /* 01101100 */
- 0xfe, /* 11111110 */
- 0x6c, /* 01101100 */
- 0x6c, /* 01101100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 36 0x24 '$' */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0xc2, /* 11000010 */
- 0xc0, /* 11000000 */
- 0x7c, /* 01111100 */
- 0x06, /* 00000110 */
- 0x06, /* 00000110 */
- 0x86, /* 10000110 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 37 0x25 '%' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xc2, /* 11000010 */
- 0xc6, /* 11000110 */
- 0x0c, /* 00001100 */
- 0x18, /* 00011000 */
- 0x30, /* 00110000 */
- 0x60, /* 01100000 */
- 0xc6, /* 11000110 */
- 0x86, /* 10000110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 38 0x26 '&' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x38, /* 00111000 */
- 0x6c, /* 01101100 */
- 0x6c, /* 01101100 */
- 0x38, /* 00111000 */
- 0x76, /* 01110110 */
- 0xdc, /* 11011100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0x76, /* 01110110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 39 0x27 ''' */
- 0x00, /* 00000000 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x60, /* 01100000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 40 0x28 '(' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x0c, /* 00001100 */
- 0x18, /* 00011000 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x18, /* 00011000 */
- 0x0c, /* 00001100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 41 0x29 ')' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x30, /* 00110000 */
- 0x18, /* 00011000 */
- 0x0c, /* 00001100 */
- 0x0c, /* 00001100 */
- 0x0c, /* 00001100 */
- 0x0c, /* 00001100 */
- 0x0c, /* 00001100 */
- 0x0c, /* 00001100 */
- 0x18, /* 00011000 */
- 0x30, /* 00110000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 42 0x2a '*' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x66, /* 01100110 */
- 0x3c, /* 00111100 */
- 0xff, /* 11111111 */
- 0x3c, /* 00111100 */
- 0x66, /* 01100110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 43 0x2b '+' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x7e, /* 01111110 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 44 0x2c ',' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x30, /* 00110000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 45 0x2d '-' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xfe, /* 11111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 46 0x2e '.' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 47 0x2f '/' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x02, /* 00000010 */
- 0x06, /* 00000110 */
- 0x0c, /* 00001100 */
- 0x18, /* 00011000 */
- 0x30, /* 00110000 */
- 0x60, /* 01100000 */
- 0xc0, /* 11000000 */
- 0x80, /* 10000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 48 0x30 '0' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x38, /* 00111000 */
- 0x6c, /* 01101100 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xd6, /* 11010110 */
- 0xd6, /* 11010110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x6c, /* 01101100 */
- 0x38, /* 00111000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 49 0x31 '1' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x38, /* 00111000 */
- 0x78, /* 01111000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x7e, /* 01111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 50 0x32 '2' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0x06, /* 00000110 */
- 0x0c, /* 00001100 */
- 0x18, /* 00011000 */
- 0x30, /* 00110000 */
- 0x60, /* 01100000 */
- 0xc0, /* 11000000 */
- 0xc6, /* 11000110 */
- 0xfe, /* 11111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 51 0x33 '3' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0x06, /* 00000110 */
- 0x06, /* 00000110 */
- 0x3c, /* 00111100 */
- 0x06, /* 00000110 */
- 0x06, /* 00000110 */
- 0x06, /* 00000110 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 52 0x34 '4' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x0c, /* 00001100 */
- 0x1c, /* 00011100 */
- 0x3c, /* 00111100 */
- 0x6c, /* 01101100 */
- 0xcc, /* 11001100 */
- 0xfe, /* 11111110 */
- 0x0c, /* 00001100 */
- 0x0c, /* 00001100 */
- 0x0c, /* 00001100 */
- 0x1e, /* 00011110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 53 0x35 '5' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xfe, /* 11111110 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xfc, /* 11111100 */
- 0x06, /* 00000110 */
- 0x06, /* 00000110 */
- 0x06, /* 00000110 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 54 0x36 '6' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x38, /* 00111000 */
- 0x60, /* 01100000 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xfc, /* 11111100 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 55 0x37 '7' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xfe, /* 11111110 */
- 0xc6, /* 11000110 */
- 0x06, /* 00000110 */
- 0x06, /* 00000110 */
- 0x0c, /* 00001100 */
- 0x18, /* 00011000 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 56 0x38 '8' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 57 0x39 '9' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x7e, /* 01111110 */
- 0x06, /* 00000110 */
- 0x06, /* 00000110 */
- 0x06, /* 00000110 */
- 0x0c, /* 00001100 */
- 0x78, /* 01111000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 58 0x3a ':' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 59 0x3b ';' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x30, /* 00110000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 60 0x3c '<' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x06, /* 00000110 */
- 0x0c, /* 00001100 */
- 0x18, /* 00011000 */
- 0x30, /* 00110000 */
- 0x60, /* 01100000 */
- 0x30, /* 00110000 */
- 0x18, /* 00011000 */
- 0x0c, /* 00001100 */
- 0x06, /* 00000110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 61 0x3d '=' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7e, /* 01111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7e, /* 01111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 62 0x3e '>' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x60, /* 01100000 */
- 0x30, /* 00110000 */
- 0x18, /* 00011000 */
- 0x0c, /* 00001100 */
- 0x06, /* 00000110 */
- 0x0c, /* 00001100 */
- 0x18, /* 00011000 */
- 0x30, /* 00110000 */
- 0x60, /* 01100000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 63 0x3f '?' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x0c, /* 00001100 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 64 0x40 '@' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xde, /* 11011110 */
- 0xde, /* 11011110 */
- 0xde, /* 11011110 */
- 0xdc, /* 11011100 */
- 0xc0, /* 11000000 */
- 0x7c, /* 01111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 65 0x41 'A' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x10, /* 00010000 */
- 0x38, /* 00111000 */
- 0x6c, /* 01101100 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xfe, /* 11111110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 66 0x42 'B' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xfc, /* 11111100 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x7c, /* 01111100 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0xfc, /* 11111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 67 0x43 'C' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x3c, /* 00111100 */
- 0x66, /* 01100110 */
- 0xc2, /* 11000010 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xc2, /* 11000010 */
- 0x66, /* 01100110 */
- 0x3c, /* 00111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 68 0x44 'D' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xf8, /* 11111000 */
- 0x6c, /* 01101100 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x6c, /* 01101100 */
- 0xf8, /* 11111000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 69 0x45 'E' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xfe, /* 11111110 */
- 0x66, /* 01100110 */
- 0x62, /* 01100010 */
- 0x68, /* 01101000 */
- 0x78, /* 01111000 */
- 0x68, /* 01101000 */
- 0x60, /* 01100000 */
- 0x62, /* 01100010 */
- 0x66, /* 01100110 */
- 0xfe, /* 11111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 70 0x46 'F' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xfe, /* 11111110 */
- 0x66, /* 01100110 */
- 0x62, /* 01100010 */
- 0x68, /* 01101000 */
- 0x78, /* 01111000 */
- 0x68, /* 01101000 */
- 0x60, /* 01100000 */
- 0x60, /* 01100000 */
- 0x60, /* 01100000 */
- 0xf0, /* 11110000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 71 0x47 'G' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x3c, /* 00111100 */
- 0x66, /* 01100110 */
- 0xc2, /* 11000010 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xde, /* 11011110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x66, /* 01100110 */
- 0x3a, /* 00111010 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 72 0x48 'H' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xfe, /* 11111110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 73 0x49 'I' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x3c, /* 00111100 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x3c, /* 00111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 74 0x4a 'J' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x1e, /* 00011110 */
- 0x0c, /* 00001100 */
- 0x0c, /* 00001100 */
- 0x0c, /* 00001100 */
- 0x0c, /* 00001100 */
- 0x0c, /* 00001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0x78, /* 01111000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 75 0x4b 'K' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xe6, /* 11100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x6c, /* 01101100 */
- 0x78, /* 01111000 */
- 0x78, /* 01111000 */
- 0x6c, /* 01101100 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0xe6, /* 11100110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 76 0x4c 'L' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xf0, /* 11110000 */
- 0x60, /* 01100000 */
- 0x60, /* 01100000 */
- 0x60, /* 01100000 */
- 0x60, /* 01100000 */
- 0x60, /* 01100000 */
- 0x60, /* 01100000 */
- 0x62, /* 01100010 */
- 0x66, /* 01100110 */
- 0xfe, /* 11111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 77 0x4d 'M' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xc6, /* 11000110 */
- 0xee, /* 11101110 */
- 0xfe, /* 11111110 */
- 0xfe, /* 11111110 */
- 0xd6, /* 11010110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 78 0x4e 'N' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xc6, /* 11000110 */
- 0xe6, /* 11100110 */
- 0xf6, /* 11110110 */
- 0xfe, /* 11111110 */
- 0xde, /* 11011110 */
- 0xce, /* 11001110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 79 0x4f 'O' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 80 0x50 'P' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xfc, /* 11111100 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x7c, /* 01111100 */
- 0x60, /* 01100000 */
- 0x60, /* 01100000 */
- 0x60, /* 01100000 */
- 0x60, /* 01100000 */
- 0xf0, /* 11110000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 81 0x51 'Q' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xd6, /* 11010110 */
- 0xde, /* 11011110 */
- 0x7c, /* 01111100 */
- 0x0c, /* 00001100 */
- 0x0e, /* 00001110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 82 0x52 'R' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xfc, /* 11111100 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x7c, /* 01111100 */
- 0x6c, /* 01101100 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0xe6, /* 11100110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 83 0x53 'S' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x60, /* 01100000 */
- 0x38, /* 00111000 */
- 0x0c, /* 00001100 */
- 0x06, /* 00000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 84 0x54 'T' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7e, /* 01111110 */
- 0x7e, /* 01111110 */
- 0x5a, /* 01011010 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x3c, /* 00111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 85 0x55 'U' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 86 0x56 'V' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x6c, /* 01101100 */
- 0x38, /* 00111000 */
- 0x10, /* 00010000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 87 0x57 'W' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xd6, /* 11010110 */
- 0xd6, /* 11010110 */
- 0xd6, /* 11010110 */
- 0xfe, /* 11111110 */
- 0xee, /* 11101110 */
- 0x6c, /* 01101100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 88 0x58 'X' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x6c, /* 01101100 */
- 0x7c, /* 01111100 */
- 0x38, /* 00111000 */
- 0x38, /* 00111000 */
- 0x7c, /* 01111100 */
- 0x6c, /* 01101100 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 89 0x59 'Y' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x3c, /* 00111100 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x3c, /* 00111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 90 0x5a 'Z' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xfe, /* 11111110 */
- 0xc6, /* 11000110 */
- 0x86, /* 10000110 */
- 0x0c, /* 00001100 */
- 0x18, /* 00011000 */
- 0x30, /* 00110000 */
- 0x60, /* 01100000 */
- 0xc2, /* 11000010 */
- 0xc6, /* 11000110 */
- 0xfe, /* 11111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 91 0x5b '[' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x3c, /* 00111100 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x3c, /* 00111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 92 0x5c '\' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x80, /* 10000000 */
- 0xc0, /* 11000000 */
- 0xe0, /* 11100000 */
- 0x70, /* 01110000 */
- 0x38, /* 00111000 */
- 0x1c, /* 00011100 */
- 0x0e, /* 00001110 */
- 0x06, /* 00000110 */
- 0x02, /* 00000010 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 93 0x5d ']' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x3c, /* 00111100 */
- 0x0c, /* 00001100 */
- 0x0c, /* 00001100 */
- 0x0c, /* 00001100 */
- 0x0c, /* 00001100 */
- 0x0c, /* 00001100 */
- 0x0c, /* 00001100 */
- 0x0c, /* 00001100 */
- 0x0c, /* 00001100 */
- 0x3c, /* 00111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 94 0x5e '^' */
- 0x10, /* 00010000 */
- 0x38, /* 00111000 */
- 0x6c, /* 01101100 */
- 0xc6, /* 11000110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 95 0x5f '_' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xff, /* 11111111 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 96 0x60 '`' */
- 0x00, /* 00000000 */
- 0x30, /* 00110000 */
- 0x18, /* 00011000 */
- 0x0c, /* 00001100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 97 0x61 'a' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x78, /* 01111000 */
- 0x0c, /* 00001100 */
- 0x7c, /* 01111100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0x76, /* 01110110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 98 0x62 'b' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xe0, /* 11100000 */
- 0x60, /* 01100000 */
- 0x60, /* 01100000 */
- 0x78, /* 01111000 */
- 0x6c, /* 01101100 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x7c, /* 01111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 99 0x63 'c' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 100 0x64 'd' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x1c, /* 00011100 */
- 0x0c, /* 00001100 */
- 0x0c, /* 00001100 */
- 0x3c, /* 00111100 */
- 0x6c, /* 01101100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0x76, /* 01110110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 101 0x65 'e' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0xfe, /* 11111110 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 102 0x66 'f' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x1c, /* 00011100 */
- 0x36, /* 00110110 */
- 0x32, /* 00110010 */
- 0x30, /* 00110000 */
- 0x78, /* 01111000 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x78, /* 01111000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 103 0x67 'g' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x76, /* 01110110 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0x7c, /* 01111100 */
- 0x0c, /* 00001100 */
- 0xcc, /* 11001100 */
- 0x78, /* 01111000 */
- 0x00, /* 00000000 */
-
- /* 104 0x68 'h' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xe0, /* 11100000 */
- 0x60, /* 01100000 */
- 0x60, /* 01100000 */
- 0x6c, /* 01101100 */
- 0x76, /* 01110110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0xe6, /* 11100110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 105 0x69 'i' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x38, /* 00111000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x3c, /* 00111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 106 0x6a 'j' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x06, /* 00000110 */
- 0x06, /* 00000110 */
- 0x00, /* 00000000 */
- 0x0e, /* 00001110 */
- 0x06, /* 00000110 */
- 0x06, /* 00000110 */
- 0x06, /* 00000110 */
- 0x06, /* 00000110 */
- 0x06, /* 00000110 */
- 0x06, /* 00000110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x3c, /* 00111100 */
- 0x00, /* 00000000 */
-
- /* 107 0x6b 'k' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xe0, /* 11100000 */
- 0x60, /* 01100000 */
- 0x60, /* 01100000 */
- 0x66, /* 01100110 */
- 0x6c, /* 01101100 */
- 0x78, /* 01111000 */
- 0x78, /* 01111000 */
- 0x6c, /* 01101100 */
- 0x66, /* 01100110 */
- 0xe6, /* 11100110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 108 0x6c 'l' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x38, /* 00111000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x3c, /* 00111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 109 0x6d 'm' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xec, /* 11101100 */
- 0xfe, /* 11111110 */
- 0xd6, /* 11010110 */
- 0xd6, /* 11010110 */
- 0xd6, /* 11010110 */
- 0xd6, /* 11010110 */
- 0xc6, /* 11000110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 110 0x6e 'n' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xdc, /* 11011100 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 111 0x6f 'o' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 112 0x70 'p' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xdc, /* 11011100 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x7c, /* 01111100 */
- 0x60, /* 01100000 */
- 0x60, /* 01100000 */
- 0xf0, /* 11110000 */
- 0x00, /* 00000000 */
-
- /* 113 0x71 'q' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x76, /* 01110110 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0x7c, /* 01111100 */
- 0x0c, /* 00001100 */
- 0x0c, /* 00001100 */
- 0x1e, /* 00011110 */
- 0x00, /* 00000000 */
-
- /* 114 0x72 'r' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xdc, /* 11011100 */
- 0x76, /* 01110110 */
- 0x66, /* 01100110 */
- 0x60, /* 01100000 */
- 0x60, /* 01100000 */
- 0x60, /* 01100000 */
- 0xf0, /* 11110000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 115 0x73 's' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0x60, /* 01100000 */
- 0x38, /* 00111000 */
- 0x0c, /* 00001100 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 116 0x74 't' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x10, /* 00010000 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0xfc, /* 11111100 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x36, /* 00110110 */
- 0x1c, /* 00011100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 117 0x75 'u' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0x76, /* 01110110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 118 0x76 'v' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x6c, /* 01101100 */
- 0x38, /* 00111000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 119 0x77 'w' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xd6, /* 11010110 */
- 0xd6, /* 11010110 */
- 0xd6, /* 11010110 */
- 0xfe, /* 11111110 */
- 0x6c, /* 01101100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 120 0x78 'x' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xc6, /* 11000110 */
- 0x6c, /* 01101100 */
- 0x38, /* 00111000 */
- 0x38, /* 00111000 */
- 0x38, /* 00111000 */
- 0x6c, /* 01101100 */
- 0xc6, /* 11000110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 121 0x79 'y' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x7e, /* 01111110 */
- 0x06, /* 00000110 */
- 0x0c, /* 00001100 */
- 0xf8, /* 11111000 */
- 0x00, /* 00000000 */
-
- /* 122 0x7a 'z' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xfe, /* 11111110 */
- 0xcc, /* 11001100 */
- 0x18, /* 00011000 */
- 0x30, /* 00110000 */
- 0x60, /* 01100000 */
- 0xc6, /* 11000110 */
- 0xfe, /* 11111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 123 0x7b '{' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x0e, /* 00001110 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x70, /* 01110000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x0e, /* 00001110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 124 0x7c '|' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 125 0x7d '}' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x70, /* 01110000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x0e, /* 00001110 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x70, /* 01110000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 126 0x7e '~' */
- 0x00, /* 00000000 */
- 0x76, /* 01110110 */
- 0xdc, /* 11011100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 127 0x7f '\7f' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x10, /* 00010000 */
- 0x38, /* 00111000 */
- 0x6c, /* 01101100 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xfe, /* 11111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 128 0x80 '\80' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x3c, /* 00111100 */
- 0x66, /* 01100110 */
- 0xc2, /* 11000010 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xc2, /* 11000010 */
- 0x66, /* 01100110 */
- 0x3c, /* 00111100 */
- 0x18, /* 00011000 */
- 0x70, /* 01110000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 129 0x81 '\81' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xcc, /* 11001100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0x76, /* 01110110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 130 0x82 '\82' */
- 0x00, /* 00000000 */
- 0x0c, /* 00001100 */
- 0x18, /* 00011000 */
- 0x30, /* 00110000 */
- 0x00, /* 00000000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0xfe, /* 11111110 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 131 0x83 '\83' */
- 0x00, /* 00000000 */
- 0x10, /* 00010000 */
- 0x38, /* 00111000 */
- 0x6c, /* 01101100 */
- 0x00, /* 00000000 */
- 0x78, /* 01111000 */
- 0x0c, /* 00001100 */
- 0x7c, /* 01111100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0x76, /* 01110110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 132 0x84 '\84' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xcc, /* 11001100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x78, /* 01111000 */
- 0x0c, /* 00001100 */
- 0x7c, /* 01111100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0x76, /* 01110110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 133 0x85 '\85' */
- 0x00, /* 00000000 */
- 0x60, /* 01100000 */
- 0x30, /* 00110000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x78, /* 01111000 */
- 0x0c, /* 00001100 */
- 0x7c, /* 01111100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0x76, /* 01110110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 134 0x86 '\86' */
- 0x00, /* 00000000 */
- 0x38, /* 00111000 */
- 0x6c, /* 01101100 */
- 0x38, /* 00111000 */
- 0x00, /* 00000000 */
- 0x78, /* 01111000 */
- 0x0c, /* 00001100 */
- 0x7c, /* 01111100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0x76, /* 01110110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 135 0x87 '\87' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0x18, /* 00011000 */
- 0x70, /* 01110000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 136 0x88 '\88' */
- 0x00, /* 00000000 */
- 0x10, /* 00010000 */
- 0x38, /* 00111000 */
- 0x6c, /* 01101100 */
- 0x00, /* 00000000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0xfe, /* 11111110 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 137 0x89 '\89' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xc6, /* 11000110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0xfe, /* 11111110 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 138 0x8a '\8a' */
- 0x00, /* 00000000 */
- 0x60, /* 01100000 */
- 0x30, /* 00110000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0xfe, /* 11111110 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 139 0x8b '\8b' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x66, /* 01100110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x38, /* 00111000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x3c, /* 00111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 140 0x8c '\8c' */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x3c, /* 00111100 */
- 0x66, /* 01100110 */
- 0x00, /* 00000000 */
- 0x38, /* 00111000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x3c, /* 00111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 141 0x8d '\8d' */
- 0x00, /* 00000000 */
- 0x60, /* 01100000 */
- 0x30, /* 00110000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x38, /* 00111000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x3c, /* 00111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 142 0x8e '\8e' */
- 0x00, /* 00000000 */
- 0xc6, /* 11000110 */
- 0x00, /* 00000000 */
- 0x10, /* 00010000 */
- 0x38, /* 00111000 */
- 0x6c, /* 01101100 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xfe, /* 11111110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 143 0x8f '\8f' */
- 0x38, /* 00111000 */
- 0x6c, /* 01101100 */
- 0x38, /* 00111000 */
- 0x10, /* 00010000 */
- 0x38, /* 00111000 */
- 0x6c, /* 01101100 */
- 0xc6, /* 11000110 */
- 0xfe, /* 11111110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 144 0x90 '\90' */
- 0x0c, /* 00001100 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0xfe, /* 11111110 */
- 0x66, /* 01100110 */
- 0x62, /* 01100010 */
- 0x68, /* 01101000 */
- 0x78, /* 01111000 */
- 0x68, /* 01101000 */
- 0x62, /* 01100010 */
- 0x66, /* 01100110 */
- 0xfe, /* 11111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 145 0x91 '\91' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xec, /* 11101100 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x7e, /* 01111110 */
- 0xd8, /* 11011000 */
- 0xd8, /* 11011000 */
- 0x6e, /* 01101110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 146 0x92 '\92' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x3e, /* 00111110 */
- 0x6c, /* 01101100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xfe, /* 11111110 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xce, /* 11001110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 147 0x93 '\93' */
- 0x00, /* 00000000 */
- 0x10, /* 00010000 */
- 0x38, /* 00111000 */
- 0x6c, /* 01101100 */
- 0x00, /* 00000000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 148 0x94 '\94' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xc6, /* 11000110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 149 0x95 '\95' */
- 0x00, /* 00000000 */
- 0x60, /* 01100000 */
- 0x30, /* 00110000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 150 0x96 '\96' */
- 0x00, /* 00000000 */
- 0x30, /* 00110000 */
- 0x78, /* 01111000 */
- 0xcc, /* 11001100 */
- 0x00, /* 00000000 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0x76, /* 01110110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 151 0x97 '\97' */
- 0x00, /* 00000000 */
- 0x60, /* 01100000 */
- 0x30, /* 00110000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0x76, /* 01110110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 152 0x98 '\98' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xc6, /* 11000110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x7e, /* 01111110 */
- 0x06, /* 00000110 */
- 0x0c, /* 00001100 */
- 0x78, /* 01111000 */
- 0x00, /* 00000000 */
-
- /* 153 0x99 '\99' */
- 0x00, /* 00000000 */
- 0xc6, /* 11000110 */
- 0x00, /* 00000000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 154 0x9a '\9a' */
- 0x00, /* 00000000 */
- 0xc6, /* 11000110 */
- 0x00, /* 00000000 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 155 0x9b '\9b' */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 156 0x9c '\9c' */
- 0x00, /* 00000000 */
- 0x38, /* 00111000 */
- 0x6c, /* 01101100 */
- 0x64, /* 01100100 */
- 0x60, /* 01100000 */
- 0xf0, /* 11110000 */
- 0x60, /* 01100000 */
- 0x60, /* 01100000 */
- 0x60, /* 01100000 */
- 0x60, /* 01100000 */
- 0xe6, /* 11100110 */
- 0xfc, /* 11111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 157 0x9d '\9d' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x3c, /* 00111100 */
- 0x18, /* 00011000 */
- 0x7e, /* 01111110 */
- 0x18, /* 00011000 */
- 0x7e, /* 01111110 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 158 0x9e '\9e' */
- 0x00, /* 00000000 */
- 0xf8, /* 11111000 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xf8, /* 11111000 */
- 0xc4, /* 11000100 */
- 0xcc, /* 11001100 */
- 0xde, /* 11011110 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xc6, /* 11000110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 159 0x9f '\9f' */
- 0x00, /* 00000000 */
- 0x0e, /* 00001110 */
- 0x1b, /* 00011011 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x7e, /* 01111110 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0xd8, /* 11011000 */
- 0x70, /* 01110000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 160 0xa0 ' ' */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x30, /* 00110000 */
- 0x60, /* 01100000 */
- 0x00, /* 00000000 */
- 0x78, /* 01111000 */
- 0x0c, /* 00001100 */
- 0x7c, /* 01111100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0x76, /* 01110110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 161 0xa1 '¡' */
- 0x00, /* 00000000 */
- 0x0c, /* 00001100 */
- 0x18, /* 00011000 */
- 0x30, /* 00110000 */
- 0x00, /* 00000000 */
- 0x38, /* 00111000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x3c, /* 00111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 162 0xa2 '¢' */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x30, /* 00110000 */
- 0x60, /* 01100000 */
- 0x00, /* 00000000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 163 0xa3 '£' */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x30, /* 00110000 */
- 0x60, /* 01100000 */
- 0x00, /* 00000000 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0x76, /* 01110110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 164 0xa4 '¤' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x76, /* 01110110 */
- 0xdc, /* 11011100 */
- 0x00, /* 00000000 */
- 0xdc, /* 11011100 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 165 0xa5 '¥' */
- 0x76, /* 01110110 */
- 0xdc, /* 11011100 */
- 0x00, /* 00000000 */
- 0xc6, /* 11000110 */
- 0xe6, /* 11100110 */
- 0xf6, /* 11110110 */
- 0xfe, /* 11111110 */
- 0xde, /* 11011110 */
- 0xce, /* 11001110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 166 0xa6 '¦' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x3c, /* 00111100 */
- 0x6c, /* 01101100 */
- 0x6c, /* 01101100 */
- 0x3e, /* 00111110 */
- 0x00, /* 00000000 */
- 0x7e, /* 01111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 167 0xa7 '§' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x38, /* 00111000 */
- 0x6c, /* 01101100 */
- 0x6c, /* 01101100 */
- 0x38, /* 00111000 */
- 0x00, /* 00000000 */
- 0x7c, /* 01111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 168 0xa8 '¨' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x00, /* 00000000 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x60, /* 01100000 */
- 0xc0, /* 11000000 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 169 0xa9 '©' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xfe, /* 11111110 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 170 0xaa 'ª' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xfe, /* 11111110 */
- 0x06, /* 00000110 */
- 0x06, /* 00000110 */
- 0x06, /* 00000110 */
- 0x06, /* 00000110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 171 0xab '«' */
- 0x00, /* 00000000 */
- 0x60, /* 01100000 */
- 0xe0, /* 11100000 */
- 0x62, /* 01100010 */
- 0x66, /* 01100110 */
- 0x6c, /* 01101100 */
- 0x18, /* 00011000 */
- 0x30, /* 00110000 */
- 0x60, /* 01100000 */
- 0xdc, /* 11011100 */
- 0x86, /* 10000110 */
- 0x0c, /* 00001100 */
- 0x18, /* 00011000 */
- 0x3e, /* 00111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 172 0xac '¬' */
- 0x00, /* 00000000 */
- 0x60, /* 01100000 */
- 0xe0, /* 11100000 */
- 0x62, /* 01100010 */
- 0x66, /* 01100110 */
- 0x6c, /* 01101100 */
- 0x18, /* 00011000 */
- 0x30, /* 00110000 */
- 0x66, /* 01100110 */
- 0xce, /* 11001110 */
- 0x9a, /* 10011010 */
- 0x3f, /* 00111111 */
- 0x06, /* 00000110 */
- 0x06, /* 00000110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 173 0xad '' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x3c, /* 00111100 */
- 0x3c, /* 00111100 */
- 0x3c, /* 00111100 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 174 0xae '®' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x36, /* 00110110 */
- 0x6c, /* 01101100 */
- 0xd8, /* 11011000 */
- 0x6c, /* 01101100 */
- 0x36, /* 00110110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 175 0xaf '¯' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xd8, /* 11011000 */
- 0x6c, /* 01101100 */
- 0x36, /* 00110110 */
- 0x6c, /* 01101100 */
- 0xd8, /* 11011000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 176 0xb0 '°' */
- 0x11, /* 00010001 */
- 0x44, /* 01000100 */
- 0x11, /* 00010001 */
- 0x44, /* 01000100 */
- 0x11, /* 00010001 */
- 0x44, /* 01000100 */
- 0x11, /* 00010001 */
- 0x44, /* 01000100 */
- 0x11, /* 00010001 */
- 0x44, /* 01000100 */
- 0x11, /* 00010001 */
- 0x44, /* 01000100 */
- 0x11, /* 00010001 */
- 0x44, /* 01000100 */
- 0x11, /* 00010001 */
- 0x44, /* 01000100 */
-
- /* 177 0xb1 '±' */
- 0x55, /* 01010101 */
- 0xaa, /* 10101010 */
- 0x55, /* 01010101 */
- 0xaa, /* 10101010 */
- 0x55, /* 01010101 */
- 0xaa, /* 10101010 */
- 0x55, /* 01010101 */
- 0xaa, /* 10101010 */
- 0x55, /* 01010101 */
- 0xaa, /* 10101010 */
- 0x55, /* 01010101 */
- 0xaa, /* 10101010 */
- 0x55, /* 01010101 */
- 0xaa, /* 10101010 */
- 0x55, /* 01010101 */
- 0xaa, /* 10101010 */
-
- /* 178 0xb2 '²' */
- 0xdd, /* 11011101 */
- 0x77, /* 01110111 */
- 0xdd, /* 11011101 */
- 0x77, /* 01110111 */
- 0xdd, /* 11011101 */
- 0x77, /* 01110111 */
- 0xdd, /* 11011101 */
- 0x77, /* 01110111 */
- 0xdd, /* 11011101 */
- 0x77, /* 01110111 */
- 0xdd, /* 11011101 */
- 0x77, /* 01110111 */
- 0xdd, /* 11011101 */
- 0x77, /* 01110111 */
- 0xdd, /* 11011101 */
- 0x77, /* 01110111 */
-
- /* 179 0xb3 '³' */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
-
- /* 180 0xb4 '´' */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0xf8, /* 11111000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
-
- /* 181 0xb5 'µ' */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0xf8, /* 11111000 */
- 0x18, /* 00011000 */
- 0xf8, /* 11111000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
-
- /* 182 0xb6 '¶' */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0xf6, /* 11110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
-
- /* 183 0xb7 '·' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xfe, /* 11111110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
-
- /* 184 0xb8 '¸' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xf8, /* 11111000 */
- 0x18, /* 00011000 */
- 0xf8, /* 11111000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
-
- /* 185 0xb9 '¹' */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0xf6, /* 11110110 */
- 0x06, /* 00000110 */
- 0xf6, /* 11110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
-
- /* 186 0xba 'º' */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
-
- /* 187 0xbb '»' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xfe, /* 11111110 */
- 0x06, /* 00000110 */
- 0xf6, /* 11110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
-
- /* 188 0xbc '¼' */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0xf6, /* 11110110 */
- 0x06, /* 00000110 */
- 0xfe, /* 11111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 189 0xbd '½' */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0xfe, /* 11111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 190 0xbe '¾' */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0xf8, /* 11111000 */
- 0x18, /* 00011000 */
- 0xf8, /* 11111000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 191 0xbf '¿' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xf8, /* 11111000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
-
- /* 192 0xc0 'À' */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x1f, /* 00011111 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 193 0xc1 'Á' */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0xff, /* 11111111 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 194 0xc2 'Â' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xff, /* 11111111 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
-
- /* 195 0xc3 'Ã' */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x1f, /* 00011111 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
-
- /* 196 0xc4 'Ä' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xff, /* 11111111 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 197 0xc5 'Å' */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0xff, /* 11111111 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
-
- /* 198 0xc6 'Æ' */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x1f, /* 00011111 */
- 0x18, /* 00011000 */
- 0x1f, /* 00011111 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
-
- /* 199 0xc7 'Ç' */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x37, /* 00110111 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
-
- /* 200 0xc8 'È' */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x37, /* 00110111 */
- 0x30, /* 00110000 */
- 0x3f, /* 00111111 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 201 0xc9 'É' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x3f, /* 00111111 */
- 0x30, /* 00110000 */
- 0x37, /* 00110111 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
-
- /* 202 0xca 'Ê' */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0xf7, /* 11110111 */
- 0x00, /* 00000000 */
- 0xff, /* 11111111 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 203 0xcb 'Ë' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xff, /* 11111111 */
- 0x00, /* 00000000 */
- 0xf7, /* 11110111 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
-
- /* 204 0xcc 'Ì' */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x37, /* 00110111 */
- 0x30, /* 00110000 */
- 0x37, /* 00110111 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
-
- /* 205 0xcd 'Í' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xff, /* 11111111 */
- 0x00, /* 00000000 */
- 0xff, /* 11111111 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 206 0xce 'Î' */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0xf7, /* 11110111 */
- 0x00, /* 00000000 */
- 0xf7, /* 11110111 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
-
- /* 207 0xcf 'Ï' */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0xff, /* 11111111 */
- 0x00, /* 00000000 */
- 0xff, /* 11111111 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 208 0xd0 'Ð' */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0xff, /* 11111111 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 209 0xd1 'Ñ' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xff, /* 11111111 */
- 0x00, /* 00000000 */
- 0xff, /* 11111111 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
-
- /* 210 0xd2 'Ò' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xff, /* 11111111 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
-
- /* 211 0xd3 'Ó' */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x3f, /* 00111111 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 212 0xd4 'Ô' */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x1f, /* 00011111 */
- 0x18, /* 00011000 */
- 0x1f, /* 00011111 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 213 0xd5 'Õ' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x1f, /* 00011111 */
- 0x18, /* 00011000 */
- 0x1f, /* 00011111 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
-
- /* 214 0xd6 'Ö' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x3f, /* 00111111 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
-
- /* 215 0xd7 '×' */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0xff, /* 11111111 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
-
- /* 216 0xd8 'Ø' */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0xff, /* 11111111 */
- 0x18, /* 00011000 */
- 0xff, /* 11111111 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
-
- /* 217 0xd9 'Ù' */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0xf8, /* 11111000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 218 0xda 'Ú' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x1f, /* 00011111 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
-
- /* 219 0xdb 'Û' */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
-
- /* 220 0xdc 'Ü' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
-
- /* 221 0xdd 'Ý' */
- 0xf0, /* 11110000 */
- 0xf0, /* 11110000 */
- 0xf0, /* 11110000 */
- 0xf0, /* 11110000 */
- 0xf0, /* 11110000 */
- 0xf0, /* 11110000 */
- 0xf0, /* 11110000 */
- 0xf0, /* 11110000 */
- 0xf0, /* 11110000 */
- 0xf0, /* 11110000 */
- 0xf0, /* 11110000 */
- 0xf0, /* 11110000 */
- 0xf0, /* 11110000 */
- 0xf0, /* 11110000 */
- 0xf0, /* 11110000 */
- 0xf0, /* 11110000 */
-
- /* 222 0xde 'Þ' */
- 0x0f, /* 00001111 */
- 0x0f, /* 00001111 */
- 0x0f, /* 00001111 */
- 0x0f, /* 00001111 */
- 0x0f, /* 00001111 */
- 0x0f, /* 00001111 */
- 0x0f, /* 00001111 */
- 0x0f, /* 00001111 */
- 0x0f, /* 00001111 */
- 0x0f, /* 00001111 */
- 0x0f, /* 00001111 */
- 0x0f, /* 00001111 */
- 0x0f, /* 00001111 */
- 0x0f, /* 00001111 */
- 0x0f, /* 00001111 */
- 0x0f, /* 00001111 */
-
- /* 223 0xdf 'ß' */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 224 0xe0 'à' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x76, /* 01110110 */
- 0xdc, /* 11011100 */
- 0xd8, /* 11011000 */
- 0xd8, /* 11011000 */
- 0xd8, /* 11011000 */
- 0xdc, /* 11011100 */
- 0x76, /* 01110110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 225 0xe1 'á' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x78, /* 01111000 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xd8, /* 11011000 */
- 0xcc, /* 11001100 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xcc, /* 11001100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 226 0xe2 'â' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xfe, /* 11111110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 227 0xe3 'ã' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xfe, /* 11111110 */
- 0x6c, /* 01101100 */
- 0x6c, /* 01101100 */
- 0x6c, /* 01101100 */
- 0x6c, /* 01101100 */
- 0x6c, /* 01101100 */
- 0x6c, /* 01101100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 228 0xe4 'ä' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xfe, /* 11111110 */
- 0xc6, /* 11000110 */
- 0x60, /* 01100000 */
- 0x30, /* 00110000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x30, /* 00110000 */
- 0x60, /* 01100000 */
- 0xc6, /* 11000110 */
- 0xfe, /* 11111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 229 0xe5 'å' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7e, /* 01111110 */
- 0xd8, /* 11011000 */
- 0xd8, /* 11011000 */
- 0xd8, /* 11011000 */
- 0xd8, /* 11011000 */
- 0xd8, /* 11011000 */
- 0x70, /* 01110000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 230 0xe6 'æ' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x7c, /* 01111100 */
- 0x60, /* 01100000 */
- 0x60, /* 01100000 */
- 0xc0, /* 11000000 */
- 0x00, /* 00000000 */
-
- /* 231 0xe7 'ç' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x76, /* 01110110 */
- 0xdc, /* 11011100 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 232 0xe8 'è' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7e, /* 01111110 */
- 0x18, /* 00011000 */
- 0x3c, /* 00111100 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x3c, /* 00111100 */
- 0x18, /* 00011000 */
- 0x7e, /* 01111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 233 0xe9 'é' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x38, /* 00111000 */
- 0x6c, /* 01101100 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xfe, /* 11111110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x6c, /* 01101100 */
- 0x38, /* 00111000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 234 0xea 'ê' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x38, /* 00111000 */
- 0x6c, /* 01101100 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x6c, /* 01101100 */
- 0x6c, /* 01101100 */
- 0x6c, /* 01101100 */
- 0x6c, /* 01101100 */
- 0xee, /* 11101110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 235 0xeb 'ë' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x1e, /* 00011110 */
- 0x30, /* 00110000 */
- 0x18, /* 00011000 */
- 0x0c, /* 00001100 */
- 0x3e, /* 00111110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x3c, /* 00111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 236 0xec 'ì' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7e, /* 01111110 */
- 0xdb, /* 11011011 */
- 0xdb, /* 11011011 */
- 0xdb, /* 11011011 */
- 0x7e, /* 01111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 237 0xed 'í' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x03, /* 00000011 */
- 0x06, /* 00000110 */
- 0x7e, /* 01111110 */
- 0xdb, /* 11011011 */
- 0xdb, /* 11011011 */
- 0xf3, /* 11110011 */
- 0x7e, /* 01111110 */
- 0x60, /* 01100000 */
- 0xc0, /* 11000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 238 0xee 'î' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x1c, /* 00011100 */
- 0x30, /* 00110000 */
- 0x60, /* 01100000 */
- 0x60, /* 01100000 */
- 0x7c, /* 01111100 */
- 0x60, /* 01100000 */
- 0x60, /* 01100000 */
- 0x60, /* 01100000 */
- 0x30, /* 00110000 */
- 0x1c, /* 00011100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 239 0xef 'ï' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 240 0xf0 'ð' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xfe, /* 11111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xfe, /* 11111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xfe, /* 11111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 241 0xf1 'ñ' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x7e, /* 01111110 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7e, /* 01111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 242 0xf2 'ò' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x30, /* 00110000 */
- 0x18, /* 00011000 */
- 0x0c, /* 00001100 */
- 0x06, /* 00000110 */
- 0x0c, /* 00001100 */
- 0x18, /* 00011000 */
- 0x30, /* 00110000 */
- 0x00, /* 00000000 */
- 0x7e, /* 01111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 243 0xf3 'ó' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x0c, /* 00001100 */
- 0x18, /* 00011000 */
- 0x30, /* 00110000 */
- 0x60, /* 01100000 */
- 0x30, /* 00110000 */
- 0x18, /* 00011000 */
- 0x0c, /* 00001100 */
- 0x00, /* 00000000 */
- 0x7e, /* 01111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 244 0xf4 'ô' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x0e, /* 00001110 */
- 0x1b, /* 00011011 */
- 0x1b, /* 00011011 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
-
- /* 245 0xf5 'õ' */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0xd8, /* 11011000 */
- 0xd8, /* 11011000 */
- 0xd8, /* 11011000 */
- 0x70, /* 01110000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 246 0xf6 'ö' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x7e, /* 01111110 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 247 0xf7 '÷' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x76, /* 01110110 */
- 0xdc, /* 11011100 */
- 0x00, /* 00000000 */
- 0x76, /* 01110110 */
- 0xdc, /* 11011100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 248 0xf8 'ø' */
- 0x00, /* 00000000 */
- 0x38, /* 00111000 */
- 0x6c, /* 01101100 */
- 0x6c, /* 01101100 */
- 0x38, /* 00111000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 249 0xf9 'ù' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 250 0xfa 'ú' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 251 0xfb 'û' */
- 0x00, /* 00000000 */
- 0x0f, /* 00001111 */
- 0x0c, /* 00001100 */
- 0x0c, /* 00001100 */
- 0x0c, /* 00001100 */
- 0x0c, /* 00001100 */
- 0x0c, /* 00001100 */
- 0xec, /* 11101100 */
- 0x6c, /* 01101100 */
- 0x6c, /* 01101100 */
- 0x3c, /* 00111100 */
- 0x1c, /* 00011100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 252 0xfc 'ü' */
- 0x00, /* 00000000 */
- 0x6c, /* 01101100 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 253 0xfd 'ý' */
- 0x00, /* 00000000 */
- 0x3c, /* 00111100 */
- 0x66, /* 01100110 */
- 0x0c, /* 00001100 */
- 0x18, /* 00011000 */
- 0x32, /* 00110010 */
- 0x7e, /* 01111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 254 0xfe 'þ' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7e, /* 01111110 */
- 0x7e, /* 01111110 */
- 0x7e, /* 01111110 */
- 0x7e, /* 01111110 */
- 0x7e, /* 01111110 */
- 0x7e, /* 01111110 */
- 0x7e, /* 01111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 255 0xff 'ÿ' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
-};
+++ /dev/null
-/*
- * QEMU System Emulator
- *
- * Copyright (c) 2003-2004 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "vl.h"
-#ifdef __ia64__
-#include <xen/arch-ia64.h>
-#endif
-
-#include <unistd.h>
-#include <fcntl.h>
-#include <signal.h>
-#include <time.h>
-#include <errno.h>
-#include <sys/time.h>
-
-#ifndef _WIN32
-#include <sys/times.h>
-#include <sys/wait.h>
-#include <termios.h>
-#include <sys/poll.h>
-#include <sys/mman.h>
-#include <sys/ioctl.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <dirent.h>
-#ifdef _BSD
-#include <sys/stat.h>
-#ifndef __APPLE__
-#include <libutil.h>
-#endif
-#else
-#include <linux/if.h>
-#include <linux/if_tun.h>
-#include <pty.h>
-#include <malloc.h>
-#include <linux/rtc.h>
-#endif
-#endif
-
-#if defined(CONFIG_SLIRP)
-#include "libslirp.h"
-#endif
-
-#ifdef _WIN32
-#include <malloc.h>
-#include <sys/timeb.h>
-#include <windows.h>
-#define getopt_long_only getopt_long
-#define memalign(align, size) malloc(size)
-#endif
-
-#ifdef CONFIG_SDL
-#ifdef __APPLE__
-#include <SDL/SDL.h>
-#endif
-#endif /* CONFIG_SDL */
-
-#include "exec-all.h"
-
-//#define DO_TB_FLUSH
-
-#define DEFAULT_NETWORK_SCRIPT "/etc/xen/qemu-ifup"
-
-#if !defined(CONFIG_SOFTMMU)
-#define PHYS_RAM_MAX_SIZE (256 * 1024 * 1024)
-#else
-#define PHYS_RAM_MAX_SIZE (2047 * 1024 * 1024)
-#endif
-
-#ifdef TARGET_PPC
-#define DEFAULT_RAM_SIZE 144
-#else
-#define DEFAULT_RAM_SIZE 128
-#endif
-/* in ms */
-#define GUI_REFRESH_INTERVAL 30
-#define POLLING_INTERVAL 5
-
-/* XXX: use a two level table to limit memory usage */
-#define MAX_IOPORTS 65536
-
-const char *bios_dir = CONFIG_QEMU_SHAREDIR;
-char phys_ram_file[1024];
-CPUState *global_env;
-CPUState *cpu_single_env;
-void *ioport_opaque[MAX_IOPORTS];
-IOPortReadFunc *ioport_read_table[3][MAX_IOPORTS];
-IOPortWriteFunc *ioport_write_table[3][MAX_IOPORTS];
-BlockDriverState *bs_table[MAX_DISKS], *fd_table[MAX_FD];
-int vga_ram_size;
-int bios_size;
-static DisplayState display_state;
-int nographic;
-int usevnc; /* 1=vnc only, 2=vnc and sdl */
-long vncport; /* server port */
-const char* vncconnect; /* do a reverse connect to this host*/
-const char* keyboard_layout = 0;
-int64_t ticks_per_sec;
-int boot_device = 'c';
-uint64_t ram_size;
-int domid = -1;
-static char network_script[1024];
-int pit_min_timer_count = 0;
-int nb_nics;
-char bridge[16];
-char domain_name[1024] = { 'H','V', 'M', 'X', 'E', 'N', '-'};
-NetDriverState nd_table[MAX_NICS];
-QEMUTimer *gui_timer;
-QEMUTimer *polling_timer;
-int vm_running;
-int audio_enabled = 0;
-int nic_ne2000 = 0;
-int vcpus = 1;
-int sb16_enabled = 1;
-int adlib_enabled = 1;
-int gus_enabled = 1;
-int pci_enabled = 1;
-int prep_enabled = 0;
-int rtc_utc = 1;
-int cirrus_vga_enabled = 1;
-int vga_accelerate = 1;
-int graphic_width = 800;
-int graphic_height = 600;
-int graphic_depth = 15;
-int full_screen = 0;
-int repeat_key = 1;
-int usb_enabled = 0;
-USBPort *vm_usb_ports[MAX_VM_USB_PORTS];
-USBDevice *vm_usb_hub;
-TextConsole *vga_console;
-CharDriverState *serial_hds[MAX_SERIAL_PORTS];
-int serial_summa_port = -1;
-int xc_handle;
-time_t timeoffset = 0;
-
-/***********************************************************/
-/* x86 ISA bus support */
-
-target_phys_addr_t isa_mem_base = 0;
-
-uint32_t default_ioport_readb(void *opaque, uint32_t address)
-{
-#ifdef DEBUG_UNUSED_IOPORT
- fprintf(stderr, "inb: port=0x%04x\n", address);
-#endif
- return 0xff;
-}
-
-void default_ioport_writeb(void *opaque, uint32_t address, uint32_t data)
-{
-#ifdef DEBUG_UNUSED_IOPORT
- fprintf(stderr, "outb: port=0x%04x data=0x%02x\n", address, data);
-#endif
-}
-
-/* default is to make two byte accesses */
-uint32_t default_ioport_readw(void *opaque, uint32_t address)
-{
- uint32_t data;
- data = ioport_read_table[0][address](ioport_opaque[address], address);
- address = (address + 1) & (MAX_IOPORTS - 1);
- data |= ioport_read_table[0][address](ioport_opaque[address], address) << 8;
- return data;
-}
-
-void default_ioport_writew(void *opaque, uint32_t address, uint32_t data)
-{
- ioport_write_table[0][address](ioport_opaque[address], address, data & 0xff);
- address = (address + 1) & (MAX_IOPORTS - 1);
- ioport_write_table[0][address](ioport_opaque[address], address, (data >> 8) & 0xff);
-}
-
-uint32_t default_ioport_readl(void *opaque, uint32_t address)
-{
-#ifdef DEBUG_UNUSED_IOPORT
- fprintf(stderr, "inl: port=0x%04x\n", address);
-#endif
- return 0xffffffff;
-}
-
-void default_ioport_writel(void *opaque, uint32_t address, uint32_t data)
-{
-#ifdef DEBUG_UNUSED_IOPORT
- fprintf(stderr, "outl: port=0x%04x data=0x%02x\n", address, data);
-#endif
-}
-
-void init_ioports(void)
-{
- int i;
-
- for(i = 0; i < MAX_IOPORTS; i++) {
- ioport_read_table[0][i] = default_ioport_readb;
- ioport_write_table[0][i] = default_ioport_writeb;
- ioport_read_table[1][i] = default_ioport_readw;
- ioport_write_table[1][i] = default_ioport_writew;
- ioport_read_table[2][i] = default_ioport_readl;
- ioport_write_table[2][i] = default_ioport_writel;
- }
-}
-
-/* size is the word size in byte */
-int register_ioport_read(int start, int length, int size,
- IOPortReadFunc *func, void *opaque)
-{
- int i, bsize;
-
- if (size == 1) {
- bsize = 0;
- } else if (size == 2) {
- bsize = 1;
- } else if (size == 4) {
- bsize = 2;
- } else {
- hw_error("register_ioport_read: invalid size");
- return -1;
- }
- for(i = start; i < start + length; i += size) {
- ioport_read_table[bsize][i] = func;
- if (ioport_opaque[i] != NULL && ioport_opaque[i] != opaque)
- hw_error("register_ioport_read: invalid opaque");
- ioport_opaque[i] = opaque;
- }
- return 0;
-}
-
-/* size is the word size in byte */
-int register_ioport_write(int start, int length, int size,
- IOPortWriteFunc *func, void *opaque)
-{
- int i, bsize;
-
- if (size == 1) {
- bsize = 0;
- } else if (size == 2) {
- bsize = 1;
- } else if (size == 4) {
- bsize = 2;
- } else {
- hw_error("register_ioport_write: invalid size");
- return -1;
- }
- for(i = start; i < start + length; i += size) {
- ioport_write_table[bsize][i] = func;
- if (ioport_opaque[i] != NULL && ioport_opaque[i] != opaque)
- hw_error("register_ioport_read: invalid opaque");
- ioport_opaque[i] = opaque;
- }
- return 0;
-}
-
-void isa_unassign_ioport(int start, int length)
-{
- int i;
-
- for(i = start; i < start + length; i++) {
- ioport_read_table[0][i] = default_ioport_readb;
- ioport_read_table[1][i] = default_ioport_readw;
- ioport_read_table[2][i] = default_ioport_readl;
-
- ioport_write_table[0][i] = default_ioport_writeb;
- ioport_write_table[1][i] = default_ioport_writew;
- ioport_write_table[2][i] = default_ioport_writel;
- }
-}
-
-void pstrcpy(char *buf, int buf_size, const char *str)
-{
- int c;
- char *q = buf;
-
- if (buf_size <= 0)
- return;
-
- for(;;) {
- c = *str++;
- if (c == 0 || q >= buf + buf_size - 1)
- break;
- *q++ = c;
- }
- *q = '\0';
-}
-
-/* strcat and truncate. */
-char *pstrcat(char *buf, int buf_size, const char *s)
-{
- int len;
- len = strlen(buf);
- if (len < buf_size)
- pstrcpy(buf + len, buf_size - len, s);
- return buf;
-}
-
-int strstart(const char *str, const char *val, const char **ptr)
-{
- const char *p, *q;
- p = str;
- q = val;
- while (*q != '\0') {
- if (*p != *q)
- return 0;
- p++;
- q++;
- }
- if (ptr)
- *ptr = p;
- return 1;
-}
-
-/* return the size or -1 if error */
-int get_image_size(const char *filename)
-{
- int fd, size;
- fd = open(filename, O_RDONLY | O_BINARY);
- if (fd < 0)
- return -1;
- size = lseek(fd, 0, SEEK_END);
- close(fd);
- return size;
-}
-
-/* return the size or -1 if error */
-int load_image(const char *filename, uint8_t *addr)
-{
- int fd, size;
- fd = open(filename, O_RDONLY | O_BINARY);
- if (fd < 0)
- return -1;
- size = lseek(fd, 0, SEEK_END);
- lseek(fd, 0, SEEK_SET);
- if (read(fd, addr, size) != size) {
- close(fd);
- return -1;
- }
- close(fd);
- return size;
-}
-
-void cpu_outb(CPUState *env, int addr, int val)
-{
-#ifdef DEBUG_IOPORT
- if (loglevel & CPU_LOG_IOPORT)
- fprintf(logfile, "outb: %04x %02x\n", addr, val);
-#endif
- ioport_write_table[0][addr](ioport_opaque[addr], addr, val);
-}
-
-void cpu_outw(CPUState *env, int addr, int val)
-{
-#ifdef DEBUG_IOPORT
- if (loglevel & CPU_LOG_IOPORT)
- fprintf(logfile, "outw: %04x %04x\n", addr, val);
-#endif
- ioport_write_table[1][addr](ioport_opaque[addr], addr, val);
-}
-
-void cpu_outl(CPUState *env, int addr, int val)
-{
-#ifdef DEBUG_IOPORT
- if (loglevel & CPU_LOG_IOPORT)
- fprintf(logfile, "outl: %04x %08x\n", addr, val);
-#endif
- ioport_write_table[2][addr](ioport_opaque[addr], addr, val);
-}
-
-int cpu_inb(CPUState *env, int addr)
-{
- int val;
- val = ioport_read_table[0][addr](ioport_opaque[addr], addr);
-#ifdef DEBUG_IOPORT
- if (loglevel & CPU_LOG_IOPORT)
- fprintf(logfile, "inb : %04x %02x\n", addr, val);
-#endif
- return val;
-}
-
-int cpu_inw(CPUState *env, int addr)
-{
- int val;
- val = ioport_read_table[1][addr](ioport_opaque[addr], addr);
-#ifdef DEBUG_IOPORT
- if (loglevel & CPU_LOG_IOPORT)
- fprintf(logfile, "inw : %04x %04x\n", addr, val);
-#endif
- return val;
-}
-
-int cpu_inl(CPUState *env, int addr)
-{
- int val;
- val = ioport_read_table[2][addr](ioport_opaque[addr], addr);
-#ifdef DEBUG_IOPORT
- if (loglevel & CPU_LOG_IOPORT)
- fprintf(logfile, "inl : %04x %08x\n", addr, val);
-#endif
- return val;
-}
-
-/***********************************************************/
-void hw_error(const char *fmt, ...)
-{
- va_list ap;
-
- va_start(ap, fmt);
- fprintf(stderr, "qemu: hardware error: ");
- vfprintf(stderr, fmt, ap);
- fprintf(stderr, "\n");
- if (logfile) {
- fprintf(logfile, "qemu: hardware error: ");
- vfprintf(logfile, fmt, ap);
- fprintf(logfile, "\n");
- }
- va_end(ap);
- abort();
-}
-
-/***********************************************************/
-/* keyboard/mouse */
-
-static QEMUPutKBDEvent *qemu_put_kbd_event;
-static void *qemu_put_kbd_event_opaque;
-static QEMUPutMouseEvent *qemu_put_mouse_event;
-static void *qemu_put_mouse_event_opaque;
-static int qemu_put_mouse_event_absolute;
-
-void qemu_add_kbd_event_handler(QEMUPutKBDEvent *func, void *opaque)
-{
- qemu_put_kbd_event_opaque = opaque;
- qemu_put_kbd_event = func;
-}
-
-void qemu_add_mouse_event_handler(QEMUPutMouseEvent *func, void *opaque, int absolute)
-{
- qemu_put_mouse_event_opaque = opaque;
- qemu_put_mouse_event = func;
- qemu_put_mouse_event_absolute = absolute;
-}
-
-void kbd_put_keycode(int keycode)
-{
- if (qemu_put_kbd_event) {
- qemu_put_kbd_event(qemu_put_kbd_event_opaque, keycode);
- }
-}
-
-void kbd_mouse_event(int dx, int dy, int dz, int buttons_state)
-{
- if (qemu_put_mouse_event) {
- qemu_put_mouse_event(qemu_put_mouse_event_opaque,
- dx, dy, dz, buttons_state);
- }
-}
-
-int kbd_mouse_is_absolute(void)
-{
- return qemu_put_mouse_event_absolute;
-}
-
-/***********************************************************/
-/* timers */
-
-#if defined(__powerpc__)
-
-static inline uint32_t get_tbl(void)
-{
- uint32_t tbl;
- asm volatile("mftb %0" : "=r" (tbl));
- return tbl;
-}
-
-static inline uint32_t get_tbu(void)
-{
- uint32_t tbl;
- asm volatile("mftbu %0" : "=r" (tbl));
- return tbl;
-}
-
-int64_t cpu_get_real_ticks(void)
-{
- uint32_t l, h, h1;
- /* NOTE: we test if wrapping has occurred */
- do {
- h = get_tbu();
- l = get_tbl();
- h1 = get_tbu();
- } while (h != h1);
- return ((int64_t)h << 32) | l;
-}
-
-#elif defined(__i386__)
-
-int64_t cpu_get_real_ticks(void)
-{
- int64_t val;
- asm volatile ("rdtsc" : "=A" (val));
- return val;
-}
-
-#elif defined(__x86_64__)
-
-int64_t cpu_get_real_ticks(void)
-{
- uint32_t low,high;
- int64_t val;
- asm volatile("rdtsc" : "=a" (low), "=d" (high));
- val = high;
- val <<= 32;
- val |= low;
- return val;
-}
-
-#elif defined(__ia64__)
-#include "ia64_intrinsic.h"
-#define cpu_get_real_ticks() \
- __ia64_getreg(_IA64_REG_AR_ITC)
-
-#else
-#error unsupported CPU
-#endif
-
-static int64_t cpu_ticks_offset;
-static int cpu_ticks_enabled;
-int64_t cpu_virt_tsc;
-
-static inline int64_t cpu_get_ticks(void)
-{
- if (!cpu_ticks_enabled) {
- return cpu_ticks_offset;
- } else {
- return cpu_get_real_ticks() + cpu_ticks_offset;
- }
-
-}
-
-/* enable cpu_get_ticks() */
-void cpu_enable_ticks(void)
-{
- if (!cpu_ticks_enabled) {
- cpu_ticks_offset -= cpu_get_real_ticks();
- cpu_ticks_enabled = 1;
- }
-}
-
-/* disable cpu_get_ticks() : the clock is stopped. You must not call
- cpu_get_ticks() after that. */
-void cpu_disable_ticks(void)
-{
- if (cpu_ticks_enabled) {
- cpu_ticks_offset = cpu_get_ticks();
- cpu_ticks_enabled = 0;
- }
-}
-
-static int64_t get_clock(void)
-{
-#ifdef _WIN32
- struct _timeb tb;
- _ftime(&tb);
- return ((int64_t)tb.time * 1000 + (int64_t)tb.millitm) * 1000;
-#else
- struct timeval tv;
- gettimeofday(&tv, NULL);
- return tv.tv_sec * 1000000LL + tv.tv_usec;
-#endif
-}
-
-void cpu_calibrate_ticks(void)
-{
- int64_t usec, ticks;
-
- usec = get_clock();
- ticks = cpu_get_real_ticks();
-#ifdef _WIN32
- Sleep(50);
-#else
- usleep(50 * 1000);
-#endif
- usec = get_clock() - usec;
- ticks = cpu_get_real_ticks() - ticks;
- ticks_per_sec = (ticks * 1000000LL + (usec >> 1)) / usec;
-}
-
-/* compute with 96 bit intermediate result: (a*b)/c */
-uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c)
-{
- union {
- uint64_t ll;
- struct {
-#ifdef WORDS_BIGENDIAN
- uint32_t high, low;
-#else
- uint32_t low, high;
-#endif
- } l;
- } u, res;
- uint64_t rl, rh;
-
- u.ll = a;
- rl = (uint64_t)u.l.low * (uint64_t)b;
- rh = (uint64_t)u.l.high * (uint64_t)b;
- rh += (rl >> 32);
- res.l.high = rh / c;
- res.l.low = (((rh % c) << 32) + (rl & 0xffffffff)) / c;
- return res.ll;
-}
-
-#define QEMU_TIMER_REALTIME 0
-#define QEMU_TIMER_VIRTUAL 1
-
-struct QEMUClock {
- int type;
- /* XXX: add frequency */
-};
-
-struct QEMUTimer {
- QEMUClock *clock;
- int64_t expire_time;
- QEMUTimerCB *cb;
- void *opaque;
- struct QEMUTimer *next;
-};
-
-QEMUClock *rt_clock;
-QEMUClock *vm_clock;
-
-static QEMUTimer *active_timers[2];
-#ifdef _WIN32
-static MMRESULT timerID;
-#else
-/* frequency of the times() clock tick */
-static int timer_freq;
-#endif
-
-QEMUClock *qemu_new_clock(int type)
-{
- QEMUClock *clock;
- clock = qemu_mallocz(sizeof(QEMUClock));
- if (!clock)
- return NULL;
- clock->type = type;
- return clock;
-}
-
-QEMUTimer *qemu_new_timer(QEMUClock *clock, QEMUTimerCB *cb, void *opaque)
-{
- QEMUTimer *ts;
-
- ts = qemu_mallocz(sizeof(QEMUTimer));
- ts->clock = clock;
- ts->cb = cb;
- ts->opaque = opaque;
- return ts;
-}
-
-void qemu_free_timer(QEMUTimer *ts)
-{
- qemu_free(ts);
-}
-
-/* stop a timer, but do not dealloc it */
-void qemu_del_timer(QEMUTimer *ts)
-{
- QEMUTimer **pt, *t;
-
- /* NOTE: this code must be signal safe because
- qemu_timer_expired() can be called from a signal. */
- pt = &active_timers[ts->clock->type];
- for(;;) {
- t = *pt;
- if (!t)
- break;
- if (t == ts) {
- *pt = t->next;
- break;
- }
- pt = &t->next;
- }
-}
-
-/* modify the current timer so that it will be fired when current_time
- >= expire_time. The corresponding callback will be called. */
-void qemu_mod_timer(QEMUTimer *ts, int64_t expire_time)
-{
- QEMUTimer **pt, *t;
-
- qemu_del_timer(ts);
-
- /* add the timer in the sorted list */
- /* NOTE: this code must be signal safe because
- qemu_timer_expired() can be called from a signal. */
- pt = &active_timers[ts->clock->type];
- for(;;) {
- t = *pt;
- if (!t)
- break;
- if (t->expire_time > expire_time)
- break;
- pt = &t->next;
- }
- ts->expire_time = expire_time;
- ts->next = *pt;
- *pt = ts;
-}
-
-int qemu_timer_pending(QEMUTimer *ts)
-{
- QEMUTimer *t;
- for(t = active_timers[ts->clock->type]; t != NULL; t = t->next) {
- if (t == ts)
- return 1;
- }
- return 0;
-}
-
-static inline int qemu_timer_expired(QEMUTimer *timer_head, int64_t current_time)
-{
- if (!timer_head)
- return 0;
- return (timer_head->expire_time <= current_time);
-}
-
-static void qemu_run_timers(QEMUTimer **ptimer_head, int64_t current_time)
-{
- QEMUTimer *ts;
-
- for(;;) {
- ts = *ptimer_head;
- if (!ts || ts->expire_time > current_time)
- break;
- /* remove timer from the list before calling the callback */
- *ptimer_head = ts->next;
- ts->next = NULL;
-
- /* run the callback (the timer list can be modified) */
- ts->cb(ts->opaque);
- }
-}
-
-int64_t qemu_get_clock(QEMUClock *clock)
-{
- switch(clock->type) {
- case QEMU_TIMER_REALTIME:
-#ifdef _WIN32
- return GetTickCount();
-#else
- {
- struct tms tp;
-
- /* Note that using gettimeofday() is not a good solution
- for timers because its value change when the date is
- modified. */
- if (timer_freq == 100) {
- return times(&tp) * 10;
- } else {
- return ((int64_t)times(&tp) * 1000) / timer_freq;
- }
- }
-#endif
- default:
- case QEMU_TIMER_VIRTUAL:
- return cpu_get_ticks();
- }
-}
-
-/* save a timer */
-void qemu_put_timer(QEMUFile *f, QEMUTimer *ts)
-{
- uint64_t expire_time;
-
- if (qemu_timer_pending(ts)) {
- expire_time = ts->expire_time;
- } else {
- expire_time = -1;
- }
- qemu_put_be64(f, expire_time);
-}
-
-void qemu_get_timer(QEMUFile *f, QEMUTimer *ts)
-{
- uint64_t expire_time;
-
- expire_time = qemu_get_be64(f);
- if (expire_time != -1) {
- qemu_mod_timer(ts, expire_time);
- } else {
- qemu_del_timer(ts);
- }
-}
-
-static void init_timers(void)
-{
- rt_clock = qemu_new_clock(QEMU_TIMER_REALTIME);
- vm_clock = qemu_new_clock(QEMU_TIMER_VIRTUAL);
-
-#ifdef _WIN32
- {
- int count=0;
- timerID = timeSetEvent(10, // interval (ms)
- 0, // resolution
- host_alarm_handler, // function
- (DWORD)&count, // user parameter
- TIME_PERIODIC | TIME_CALLBACK_FUNCTION);
- if( !timerID ) {
- fprintf(logfile, "failed timer alarm");
- exit(1);
- }
- }
- pit_min_timer_count = ((uint64_t)10000 * PIT_FREQ) / 1000000;
-#else
- {
- /* get times() syscall frequency */
- timer_freq = sysconf(_SC_CLK_TCK);
-
-#ifndef TARGET_HVM
- /* timer signal */
- sigfillset(&act.sa_mask);
- act.sa_flags = 0;
-#if defined (TARGET_I386) && defined(USE_CODE_COPY)
- act.sa_flags |= SA_ONSTACK;
-#endif
- act.sa_handler = host_alarm_handler;
- sigaction(SIGALRM, &act, NULL);
-
- itv.it_interval.tv_sec = 0;
- itv.it_interval.tv_usec = 1000;
- itv.it_value.tv_sec = 0;
- itv.it_value.tv_usec = 10 * 1000;
- setitimer(ITIMER_REAL, &itv, NULL);
- /* we probe the tick duration of the kernel to inform the user if
- the emulated kernel requested a too high timer frequency */
- getitimer(ITIMER_REAL, &itv);
-
-#if defined(__linux__)
- if (itv.it_interval.tv_usec > 1000) {
- /* try to use /dev/rtc to have a faster timer */
- if (start_rtc_timer() < 0)
- goto use_itimer;
- /* disable itimer */
- itv.it_interval.tv_sec = 0;
- itv.it_interval.tv_usec = 0;
- itv.it_value.tv_sec = 0;
- itv.it_value.tv_usec = 0;
- setitimer(ITIMER_REAL, &itv, NULL);
-
- /* use the RTC */
- sigaction(SIGIO, &act, NULL);
- fcntl(rtc_fd, F_SETFL, O_ASYNC);
- fcntl(rtc_fd, F_SETOWN, getpid());
- } else
-#endif /* defined(__linux__) */
- {
- use_itimer:
- pit_min_timer_count = ((uint64_t)itv.it_interval.tv_usec *
- PIT_FREQ) / 1000000;
- }
-#endif /* TARGET_HVM */
- }
-#endif
-}
-
-void quit_timers(void)
-{
-#ifdef _WIN32
- timeKillEvent(timerID);
-#endif
-}
-
-/***********************************************************/
-/* character device */
-
-int qemu_chr_write(CharDriverState *s, const uint8_t *buf, int len)
-{
- return s->chr_write(s, buf, len);
-}
-
-void qemu_chr_printf(CharDriverState *s, const char *fmt, ...)
-{
- char buf[4096];
- va_list ap;
- va_start(ap, fmt);
- vsnprintf(buf, sizeof(buf), fmt, ap);
- qemu_chr_write(s, buf, strlen(buf));
- va_end(ap);
-}
-
-void qemu_chr_send_event(CharDriverState *s, int event)
-{
- if (s->chr_send_event)
- s->chr_send_event(s, event);
-}
-
-void qemu_chr_add_read_handler(CharDriverState *s,
- IOCanRWHandler *fd_can_read,
- IOReadHandler *fd_read, void *opaque)
-{
- s->chr_add_read_handler(s, fd_can_read, fd_read, opaque);
-}
-
-void qemu_chr_add_event_handler(CharDriverState *s, IOEventHandler *chr_event)
-{
- s->chr_event = chr_event;
-}
-
-static int null_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
-{
- return len;
-}
-
-static void null_chr_add_read_handler(CharDriverState *chr,
- IOCanRWHandler *fd_can_read,
- IOReadHandler *fd_read, void *opaque)
-{
-}
-
-CharDriverState *qemu_chr_open_null(void)
-{
- CharDriverState *chr;
-
- chr = qemu_mallocz(sizeof(CharDriverState));
- if (!chr)
- return NULL;
- chr->chr_write = null_chr_write;
- chr->chr_add_read_handler = null_chr_add_read_handler;
- return chr;
-}
-
-#ifndef _WIN32
-
-typedef struct {
- int fd_in, fd_out;
- /* for nographic stdio only */
- IOCanRWHandler *fd_can_read;
- IOReadHandler *fd_read;
- void *fd_opaque;
-} FDCharDriver;
-
-#define STDIO_MAX_CLIENTS 2
-
-static int stdio_nb_clients;
-static CharDriverState *stdio_clients[STDIO_MAX_CLIENTS];
-
-static int unix_write(int fd, const uint8_t *buf, int len1)
-{
- int ret,sel_ret,len;
- int max_fd;
- fd_set writefds;
- struct timeval timeout;
-
- max_fd = fd;
-
- len = len1;
- while (len > 0) {
- FD_ZERO(&writefds);
- FD_SET(fd, &writefds);
- timeout.tv_sec = 0;
- timeout.tv_usec = 0;
- sel_ret = select(max_fd + 1, NULL, &writefds, 0, &timeout);
- if (sel_ret <= 0) {
- /* Timeout or select error */
- return -1;
- } else {
- ret = write(fd, buf, len);
- if (ret < 0) {
- if (errno != EINTR && errno != EAGAIN)
- return -1;
- } else if (ret == 0) {
- break;
- } else {
- buf += ret;
- len -= ret;
- }
- }
- }
- return len1 - len;
-}
-
-static int fd_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
-{
- FDCharDriver *s = chr->opaque;
- return unix_write(s->fd_out, buf, len);
-}
-
-static void fd_chr_add_read_handler(CharDriverState *chr,
- IOCanRWHandler *fd_can_read,
- IOReadHandler *fd_read, void *opaque)
-{
- FDCharDriver *s = chr->opaque;
-
- if (nographic && s->fd_in == 0) {
- s->fd_can_read = fd_can_read;
- s->fd_read = fd_read;
- s->fd_opaque = opaque;
- } else {
- qemu_add_fd_read_handler(s->fd_in, fd_can_read, fd_read, opaque);
- }
-}
-
-/* open a character device to a unix fd */
-CharDriverState *qemu_chr_open_fd(int fd_in, int fd_out)
-{
- CharDriverState *chr;
- FDCharDriver *s;
-
- chr = qemu_mallocz(sizeof(CharDriverState));
- if (!chr)
- return NULL;
- s = qemu_mallocz(sizeof(FDCharDriver));
- if (!s) {
- free(chr);
- return NULL;
- }
- s->fd_in = fd_in;
- s->fd_out = fd_out;
- chr->opaque = s;
- chr->chr_write = fd_chr_write;
- chr->chr_add_read_handler = fd_chr_add_read_handler;
- return chr;
-}
-
-/* for STDIO, we handle the case where several clients use it
- (nographic mode) */
-
-#define TERM_ESCAPE 0x01 /* ctrl-a is used for escape */
-
-static int term_got_escape, client_index;
-
-void term_print_help(void)
-{
- printf("\n"
- "C-a h print this help\n"
- "C-a x exit emulator\n"
- "C-a s save disk data back to file (if -snapshot)\n"
- "C-a b send break (magic sysrq)\n"
- "C-a c switch between console and monitor\n"
- "C-a C-a send C-a\n"
- );
-}
-
-/* called when a char is received */
-static void stdio_received_byte(int ch)
-{
- if (term_got_escape) {
- term_got_escape = 0;
- switch(ch) {
- case 'h':
- term_print_help();
- break;
- case 'x':
- exit(0);
- break;
- case 's':
- {
- int i;
- for (i = 0; i < MAX_DISKS; i++) {
- if (bs_table[i])
- bdrv_commit(bs_table[i]);
- }
- }
- break;
- case 'b':
- if (client_index < stdio_nb_clients) {
- CharDriverState *chr;
- FDCharDriver *s;
-
- chr = stdio_clients[client_index];
- s = chr->opaque;
- chr->chr_event(s->fd_opaque, CHR_EVENT_BREAK);
- }
- break;
- case 'c':
- client_index++;
- if (client_index >= stdio_nb_clients)
- client_index = 0;
- if (client_index == 0) {
- /* send a new line in the monitor to get the prompt */
- ch = '\r';
- goto send_char;
- }
- break;
- case TERM_ESCAPE:
- goto send_char;
- }
- } else if (ch == TERM_ESCAPE) {
- term_got_escape = 1;
- } else {
- send_char:
- if (client_index < stdio_nb_clients) {
- uint8_t buf[1];
- CharDriverState *chr;
- FDCharDriver *s;
-
- chr = stdio_clients[client_index];
- s = chr->opaque;
- buf[0] = ch;
- /* XXX: should queue the char if the device is not
- ready */
- if (s->fd_can_read(s->fd_opaque) > 0)
- s->fd_read(s->fd_opaque, buf, 1);
- }
- }
-}
-
-static int stdio_can_read(void *opaque)
-{
- /* XXX: not strictly correct */
- return 1;
-}
-
-static void stdio_read(void *opaque, const uint8_t *buf, int size)
-{
- int i;
- for(i = 0; i < size; i++)
- stdio_received_byte(buf[i]);
-}
-
-/* init terminal so that we can grab keys */
-static struct termios oldtty;
-static int old_fd0_flags;
-
-static void term_exit(void)
-{
- tcsetattr (0, TCSANOW, &oldtty);
- fcntl(0, F_SETFL, old_fd0_flags);
-}
-
-static void term_init(void)
-{
- struct termios tty;
-
- tcgetattr (0, &tty);
- oldtty = tty;
- old_fd0_flags = fcntl(0, F_GETFL);
-
- tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
- |INLCR|IGNCR|ICRNL|IXON);
- tty.c_oflag |= OPOST;
- tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN);
- /* if graphical mode, we allow Ctrl-C handling */
- if (nographic)
- tty.c_lflag &= ~ISIG;
- tty.c_cflag &= ~(CSIZE|PARENB);
- tty.c_cflag |= CS8;
- tty.c_cc[VMIN] = 1;
- tty.c_cc[VTIME] = 0;
-
- tcsetattr (0, TCSANOW, &tty);
-
- atexit(term_exit);
-
- fcntl(0, F_SETFL, O_NONBLOCK);
-}
-
-CharDriverState *qemu_chr_open_stdio(void)
-{
- CharDriverState *chr;
-
- if (nographic) {
- if (stdio_nb_clients >= STDIO_MAX_CLIENTS)
- return NULL;
- chr = qemu_chr_open_fd(0, 1);
- if (stdio_nb_clients == 0)
- qemu_add_fd_read_handler(0, stdio_can_read, stdio_read, NULL);
- client_index = stdio_nb_clients;
- } else {
- if (stdio_nb_clients != 0)
- return NULL;
- chr = qemu_chr_open_fd(0, 1);
- }
- stdio_clients[stdio_nb_clients++] = chr;
- if (stdio_nb_clients == 1) {
- /* set the terminal in raw mode */
- term_init();
- }
- return chr;
-}
-
-int store_console_dev(int domid, char *pts)
-{
- int xc_handle;
- struct xs_handle *xs;
- char *path;
-
- xs = xs_daemon_open();
- if (xs == NULL) {
- fprintf(logfile, "Could not contact XenStore\n");
- return -1;
- }
-
- xc_handle = xc_interface_open();
- if (xc_handle == -1) {
- fprintf(logfile, "xc_interface_open() error\n");
- return -1;
- }
-
- path = xs_get_domain_path(xs, domid);
- if (path == NULL) {
- fprintf(logfile, "xs_get_domain_path() error\n");
- return -1;
- }
- path = realloc(path, strlen(path) + strlen("/console/tty") + 1);
- if (path == NULL) {
- fprintf(logfile, "realloc error\n");
- return -1;
- }
- strcat(path, "/console/tty");
- if (!xs_write(xs, XBT_NULL, path, pts, strlen(pts))) {
- fprintf(logfile, "xs_write for console fail");
- return -1;
- }
-
- free(path);
- xs_daemon_close(xs);
- close(xc_handle);
-
- return 0;
-}
-
-#if defined(__linux__)
-CharDriverState *qemu_chr_open_pty(void)
-{
- int master_fd, slave_fd;
- struct termios term;
-
- if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) < 0)
- return NULL;
-
- /* Set raw attributes on the pty. */
- cfmakeraw(&term);
- tcsetattr(slave_fd, TCSAFLUSH, &term);
-
- fprintf(stderr, "char device redirected to %s\n", ptsname(master_fd));
- store_console_dev(domid, ptsname(master_fd));
-
- return qemu_chr_open_fd(master_fd, master_fd);
-}
-#else
-CharDriverState *qemu_chr_open_pty(void)
-{
- return NULL;
-}
-#endif
-
-#endif /* !defined(_WIN32) */
-
-CharDriverState *qemu_chr_open(const char *filename)
-{
- if (!strcmp(filename, "vc")) {
- return text_console_init(&display_state);
- } else if (!strcmp(filename, "null")) {
- return qemu_chr_open_null();
- } else
-#ifndef _WIN32
- if (!strcmp(filename, "pty")) {
- return qemu_chr_open_pty();
- } else if (!strcmp(filename, "stdio")) {
- return qemu_chr_open_stdio();
- } else
-#endif
- {
- return NULL;
- }
-}
-
-/***********************************************************/
-/* Linux network device redirectors */
-
-void hex_dump(FILE *f, const uint8_t *buf, int size)
-{
- int len, i, j, c;
-
- for(i=0;i<size;i+=16) {
- len = size - i;
- if (len > 16)
- len = 16;
- fprintf(f, "%08x ", i);
- for(j=0;j<16;j++) {
- if (j < len)
- fprintf(f, " %02x", buf[i+j]);
- else
- fprintf(f, " ");
- }
- fprintf(f, " ");
- for(j=0;j<len;j++) {
- c = buf[i+j];
- if (c < ' ' || c > '~')
- c = '.';
- fprintf(f, "%c", c);
- }
- fprintf(f, "\n");
- }
-}
-
-void qemu_send_packet(NetDriverState *nd, const uint8_t *buf, int size)
-{
- nd->send_packet(nd, buf, size);
-}
-
-void qemu_add_read_packet(NetDriverState *nd, IOCanRWHandler *fd_can_read,
- IOReadHandler *fd_read, void *opaque)
-{
- nd->add_read_packet(nd, fd_can_read, fd_read, opaque);
-}
-
-/* dummy network adapter */
-
-static void dummy_send_packet(NetDriverState *nd, const uint8_t *buf, int size)
-{
-}
-
-static void dummy_add_read_packet(NetDriverState *nd,
- IOCanRWHandler *fd_can_read,
- IOReadHandler *fd_read, void *opaque)
-{
-}
-
-static int net_dummy_init(NetDriverState *nd)
-{
- nd->send_packet = dummy_send_packet;
- nd->add_read_packet = dummy_add_read_packet;
- pstrcpy(nd->ifname, sizeof(nd->ifname), "dummy");
- return 0;
-}
-
-#if defined(CONFIG_SLIRP)
-
-/* slirp network adapter */
-
-static void *slirp_fd_opaque;
-static IOCanRWHandler *slirp_fd_can_read;
-static IOReadHandler *slirp_fd_read;
-static int slirp_inited;
-
-int slirp_can_output(void)
-{
- return slirp_fd_can_read(slirp_fd_opaque);
-}
-
-void slirp_output(const uint8_t *pkt, int pkt_len)
-{
-#if 0
- printf("output:\n");
- hex_dump(stdout, pkt, pkt_len);
-#endif
- slirp_fd_read(slirp_fd_opaque, pkt, pkt_len);
-}
-
-static void slirp_send_packet(NetDriverState *nd, const uint8_t *buf, int size)
-{
-#if 0
- printf("input:\n");
- hex_dump(stdout, buf, size);
-#endif
- slirp_input(buf, size);
-}
-
-static void slirp_add_read_packet(NetDriverState *nd,
- IOCanRWHandler *fd_can_read,
- IOReadHandler *fd_read, void *opaque)
-{
- slirp_fd_opaque = opaque;
- slirp_fd_can_read = fd_can_read;
- slirp_fd_read = fd_read;
-}
-
-static int net_slirp_init(NetDriverState *nd)
-{
- if (!slirp_inited) {
- slirp_inited = 1;
- slirp_init();
- }
- nd->send_packet = slirp_send_packet;
- nd->add_read_packet = slirp_add_read_packet;
- pstrcpy(nd->ifname, sizeof(nd->ifname), "slirp");
- return 0;
-}
-
-static int get_str_sep(char *buf, int buf_size, const char **pp, int sep)
-{
- const char *p, *p1;
- int len;
- p = *pp;
- p1 = strchr(p, sep);
- if (!p1)
- return -1;
- len = p1 - p;
- p1++;
- if (buf_size > 0) {
- if (len > buf_size - 1)
- len = buf_size - 1;
- memcpy(buf, p, len);
- buf[len] = '\0';
- }
- *pp = p1;
- return 0;
-}
-
-static void net_slirp_redir(const char *redir_str)
-{
- int is_udp;
- char buf[256], *r;
- const char *p;
- struct in_addr guest_addr;
- int host_port, guest_port;
-
- if (!slirp_inited) {
- slirp_inited = 1;
- slirp_init();
- }
-
- p = redir_str;
- if (get_str_sep(buf, sizeof(buf), &p, ':') < 0)
- goto fail;
- if (!strcmp(buf, "tcp")) {
- is_udp = 0;
- } else if (!strcmp(buf, "udp")) {
- is_udp = 1;
- } else {
- goto fail;
- }
-
- if (get_str_sep(buf, sizeof(buf), &p, ':') < 0)
- goto fail;
- host_port = strtol(buf, &r, 0);
- if (r == buf)
- goto fail;
-
- if (get_str_sep(buf, sizeof(buf), &p, ':') < 0)
- goto fail;
- if (buf[0] == '\0') {
- pstrcpy(buf, sizeof(buf), "10.0.2.15");
- }
- if (!inet_aton(buf, &guest_addr))
- goto fail;
-
- guest_port = strtol(p, &r, 0);
- if (r == p)
- goto fail;
-
- if (slirp_redir(is_udp, host_port, guest_addr, guest_port) < 0) {
- fprintf(stderr, "qemu: could not set up redirection\n");
- exit(1);
- }
- return;
- fail:
- fprintf(stderr, "qemu: syntax: -redir [tcp|udp]:host-port:[guest-host]:guest-port\n");
- exit(1);
-}
-
-#ifndef _WIN32
-
-char smb_dir[1024];
-
-static void smb_exit(void)
-{
- DIR *d;
- struct dirent *de;
- char filename[1024];
-
- /* erase all the files in the directory */
- d = opendir(smb_dir);
- for(;;) {
- de = readdir(d);
- if (!de)
- break;
- if (strcmp(de->d_name, ".") != 0 &&
- strcmp(de->d_name, "..") != 0) {
- snprintf(filename, sizeof(filename), "%s/%s",
- smb_dir, de->d_name);
- unlink(filename);
- }
- }
- closedir(d);
- rmdir(smb_dir);
-}
-
-/* automatic user mode samba server configuration */
-void net_slirp_smb(const char *exported_dir)
-{
- char smb_conf[1024];
- char smb_cmdline[1024];
- FILE *f;
-
- if (!slirp_inited) {
- slirp_inited = 1;
- slirp_init();
- }
-
- /* XXX: better tmp dir construction */
- snprintf(smb_dir, sizeof(smb_dir), "/tmp/qemu-smb.%d", getpid());
- if (mkdir(smb_dir, 0700) < 0) {
- fprintf(stderr, "qemu: could not create samba server dir '%s'\n", smb_dir);
- exit(1);
- }
- snprintf(smb_conf, sizeof(smb_conf), "%s/%s", smb_dir, "smb.conf");
-
- f = fopen(smb_conf, "w");
- if (!f) {
- fprintf(stderr, "qemu: could not create samba server configuration file '%s'\n", smb_conf);
- exit(1);
- }
- fprintf(f,
- "[global]\n"
- "pid directory=%s\n"
- "lock directory=%s\n"
- "log file=%s/log.smbd\n"
- "smb passwd file=%s/smbpasswd\n"
- "security = share\n"
- "[qemu]\n"
- "path=%s\n"
- "read only=no\n"
- "guest ok=yes\n",
- smb_dir,
- smb_dir,
- smb_dir,
- smb_dir,
- exported_dir
- );
- fclose(f);
- atexit(smb_exit);
-
- snprintf(smb_cmdline, sizeof(smb_cmdline), "/usr/sbin/smbd -s %s",
- smb_conf);
-
- slirp_add_exec(0, smb_cmdline, 4, 139);
-}
-
-#endif /* !defined(_WIN32) */
-
-#endif /* CONFIG_SLIRP */
-
-#if !defined(_WIN32)
-#ifdef _BSD
-static int tun_open(char *ifname, int ifname_size)
-{
- int fd;
- char *dev;
- struct stat s;
-
- fd = open("/dev/tap", O_RDWR);
- if (fd < 0) {
- fprintf(stderr, "warning: could not open /dev/tap: no virtual network emulation\n");
- return -1;
- }
-
- fstat(fd, &s);
- dev = devname(s.st_rdev, S_IFCHR);
- pstrcpy(ifname, ifname_size, dev);
-
- fcntl(fd, F_SETFL, O_NONBLOCK);
- return fd;
-}
-#else
-static int tun_open(char *ifname, int ifname_size)
-{
- struct ifreq ifr;
- int fd, ret;
-
- fd = open("/dev/net/tun", O_RDWR);
- if (fd < 0) {
- fprintf(stderr, "warning: could not open /dev/net/tun: no virtual network emulation\n");
- return -1;
- }
- memset(&ifr, 0, sizeof(ifr));
- ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
- pstrcpy(ifr.ifr_name, IFNAMSIZ, "tun%d");
- ret = ioctl(fd, TUNSETIFF, (void *) &ifr);
- if (ret != 0) {
- fprintf(stderr, "warning: could not configure /dev/net/tun: no virtual network emulation\n");
- close(fd);
- return -1;
- }
- fprintf(logfile, "Connected to host network interface: %s\n", ifr.ifr_name);
- pstrcpy(ifname, ifname_size, ifr.ifr_name);
- fcntl(fd, F_SETFL, O_NONBLOCK);
- return fd;
-}
-#endif
-
-static void tun_send_packet(NetDriverState *nd, const uint8_t *buf, int size)
-{
- write(nd->fd, buf, size);
-}
-
-static void tun_add_read_packet(NetDriverState *nd,
- IOCanRWHandler *fd_can_read,
- IOReadHandler *fd_read, void *opaque)
-{
- qemu_add_fd_event_read_handler(nd->fd, fd_can_read, fd_read, opaque);
-}
-
-static int net_tun_init(NetDriverState *nd)
-{
- int pid, status;
- char *args[4];
- char **parg;
- extern int highest_fds;
-
- nd->fd = tun_open(nd->ifname, sizeof(nd->ifname));
- if (nd->fd < 0)
- return -1;
-
- if ( nd->fd > highest_fds ) highest_fds = nd->fd;
- /* try to launch network init script */
- pid = fork();
- if (pid >= 0) {
- if (pid == 0) {
- parg = args;
- *parg++ = network_script;
- *parg++ = nd->ifname;
- *parg++ = bridge;
- *parg++ = NULL;
- execv(network_script, args);
- exit(1);
- }
- while (waitpid(pid, &status, 0) != pid);
- if (!WIFEXITED(status) ||
- WEXITSTATUS(status) != 0) {
- fprintf(stderr, "%s: could not launch network script\n",
- network_script);
- }
- }
- nd->send_packet = tun_send_packet;
- nd->add_read_packet = tun_add_read_packet;
- return 0;
-}
-
-static int net_fd_init(NetDriverState *nd, int fd)
-{
- nd->fd = fd;
- nd->send_packet = tun_send_packet;
- nd->add_read_packet = tun_add_read_packet;
- pstrcpy(nd->ifname, sizeof(nd->ifname), "tunfd");
- return 0;
-}
-
-#endif /* !_WIN32 */
-
-/***********************************************************/
-/* USB devices */
-
-static int usb_device_add(const char *devname)
-{
- const char *p;
- USBDevice *dev;
- int i;
-
- if (!vm_usb_hub)
- return -1;
- for(i = 0;i < MAX_VM_USB_PORTS; i++) {
- if (!vm_usb_ports[i]->dev)
- break;
- }
- if (i == MAX_VM_USB_PORTS)
- return -1;
-
- if (strstart(devname, "host:", &p)) {
- dev = usb_host_device_open(p);
- if (!dev)
- return -1;
- } else if (!strcmp(devname, "mouse")) {
- dev = usb_mouse_init();
- if (!dev)
- return -1;
- } else if (!strcmp(devname, "tablet")) {
- dev = usb_tablet_init();
- if (!dev)
- return -1;
- } else {
- return -1;
- }
- usb_attach(vm_usb_ports[i], dev);
- return 0;
-}
-
-static int usb_device_del(const char *devname)
-{
- USBDevice *dev;
- int bus_num, addr, i;
- const char *p;
-
- if (!vm_usb_hub)
- return -1;
-
- p = strchr(devname, '.');
- if (!p)
- return -1;
- bus_num = strtoul(devname, NULL, 0);
- addr = strtoul(p + 1, NULL, 0);
- if (bus_num != 0)
- return -1;
- for(i = 0;i < MAX_VM_USB_PORTS; i++) {
- dev = vm_usb_ports[i]->dev;
- if (dev && dev->addr == addr)
- break;
- }
- if (i == MAX_VM_USB_PORTS)
- return -1;
- usb_attach(vm_usb_ports[i], NULL);
- return 0;
-}
-
-void do_usb_add(const char *devname)
-{
- int ret;
- ret = usb_device_add(devname);
- if (ret < 0)
- term_printf("Could not add USB device '%s'\n", devname);
-}
-
-void do_usb_del(const char *devname)
-{
- int ret;
- ret = usb_device_del(devname);
- if (ret < 0)
- term_printf("Could not remove USB device '%s'\n", devname);
-}
-
-void usb_info(void)
-{
- USBDevice *dev;
- int i;
- const char *speed_str;
-
- if (!vm_usb_hub) {
- term_printf("USB support not enabled\n");
- return;
- }
-
- for(i = 0; i < MAX_VM_USB_PORTS; i++) {
- dev = vm_usb_ports[i]->dev;
- if (dev) {
- term_printf("Hub port %d:\n", i);
- switch(dev->speed) {
- case USB_SPEED_LOW:
- speed_str = "1.5";
- break;
- case USB_SPEED_FULL:
- speed_str = "12";
- break;
- case USB_SPEED_HIGH:
- speed_str = "480";
- break;
- default:
- speed_str = "?";
- break;
- }
- term_printf(" Device %d.%d, speed %s Mb/s\n",
- 0, dev->addr, speed_str);
- }
- }
-}
-
-/***********************************************************/
-/* dumb display */
-
-static void dumb_update(DisplayState *ds, int x, int y, int w, int h)
-{
-}
-
-static void dumb_resize(DisplayState *ds, int w, int h)
-{
-}
-
-static void dumb_refresh(DisplayState *ds)
-{
- vga_update_display();
-}
-
-void dumb_display_init(DisplayState *ds)
-{
- ds->data = NULL;
- ds->linesize = 0;
- ds->depth = 0;
- ds->dpy_update = dumb_update;
- ds->dpy_resize = dumb_resize;
- ds->dpy_refresh = dumb_refresh;
-}
-
-#if !defined(CONFIG_SOFTMMU)
-/***********************************************************/
-/* cpu signal handler */
-static void host_segv_handler(int host_signum, siginfo_t *info,
- void *puc)
-{
- abort();
-}
-#endif
-
-/***********************************************************/
-/* I/O handling */
-
-#define MAX_IO_HANDLERS 64
-
-typedef struct IOHandlerRecord {
- int fd;
- IOCanRWHandler *fd_can_read;
- IOReadHandler *fd_read;
- void *opaque;
- /* temporary data */
- struct pollfd *ufd;
- int max_size;
- struct IOHandlerRecord *next;
-} IOHandlerRecord;
-
-static IOHandlerRecord *first_io_handler;
-static IOHandlerRecord *first_eventio_handler;
-
-int qemu_add_fd_read_handler(int fd, IOCanRWHandler *fd_can_read,
- IOReadHandler *fd_read, void *opaque)
-{
- IOHandlerRecord *ioh;
-
- ioh = qemu_mallocz(sizeof(IOHandlerRecord));
- if (!ioh)
- return -1;
- ioh->fd = fd;
- ioh->fd_can_read = fd_can_read;
- ioh->fd_read = fd_read;
- ioh->opaque = opaque;
- ioh->next = first_io_handler;
- first_io_handler = ioh;
- return 0;
-}
-
-int qemu_add_fd_event_read_handler(int fd, IOCanRWHandler *fd_can_read,
- IOReadHandler *fd_read, void *opaque)
-{
- IOHandlerRecord *ioh;
-
- ioh = qemu_mallocz(sizeof(IOHandlerRecord));
- if (!ioh)
- return -1;
- ioh->fd = fd;
- ioh->fd_can_read = fd_can_read;
- ioh->fd_read = fd_read;
- ioh->opaque = opaque;
- ioh->next = first_eventio_handler;
- first_eventio_handler = ioh;
- return 0;
-}
-
-void qemu_del_fd_read_handler(int fd)
-{
- IOHandlerRecord **pioh, *ioh;
-
- pioh = &first_io_handler;
- for(;;) {
- ioh = *pioh;
- if (ioh == NULL)
- break;
- if (ioh->fd == fd) {
- *pioh = ioh->next;
- break;
- }
- pioh = &ioh->next;
- }
-}
-
-/***********************************************************/
-/* savevm/loadvm support */
-
-void qemu_put_buffer(QEMUFile *f, const uint8_t *buf, int size)
-{
- fwrite(buf, 1, size, f);
-}
-
-void qemu_put_byte(QEMUFile *f, int v)
-{
- fputc(v, f);
-}
-
-void qemu_put_be16(QEMUFile *f, unsigned int v)
-{
- qemu_put_byte(f, v >> 8);
- qemu_put_byte(f, v);
-}
-
-void qemu_put_be32(QEMUFile *f, unsigned int v)
-{
- qemu_put_byte(f, v >> 24);
- qemu_put_byte(f, v >> 16);
- qemu_put_byte(f, v >> 8);
- qemu_put_byte(f, v);
-}
-
-void qemu_put_be64(QEMUFile *f, uint64_t v)
-{
- qemu_put_be32(f, v >> 32);
- qemu_put_be32(f, v);
-}
-
-int qemu_get_buffer(QEMUFile *f, uint8_t *buf, int size)
-{
- return fread(buf, 1, size, f);
-}
-
-int qemu_get_byte(QEMUFile *f)
-{
- int v;
- v = fgetc(f);
- if (v == EOF)
- return 0;
- else
- return v;
-}
-
-unsigned int qemu_get_be16(QEMUFile *f)
-{
- unsigned int v;
- v = qemu_get_byte(f) << 8;
- v |= qemu_get_byte(f);
- return v;
-}
-
-unsigned int qemu_get_be32(QEMUFile *f)
-{
- unsigned int v;
- v = qemu_get_byte(f) << 24;
- v |= qemu_get_byte(f) << 16;
- v |= qemu_get_byte(f) << 8;
- v |= qemu_get_byte(f);
- return v;
-}
-
-uint64_t qemu_get_be64(QEMUFile *f)
-{
- uint64_t v;
- v = (uint64_t)qemu_get_be32(f) << 32;
- v |= qemu_get_be32(f);
- return v;
-}
-
-int64_t qemu_ftell(QEMUFile *f)
-{
- return ftell(f);
-}
-
-int64_t qemu_fseek(QEMUFile *f, int64_t pos, int whence)
-{
- if (fseek(f, pos, whence) < 0)
- return -1;
- return ftell(f);
-}
-
-typedef struct SaveStateEntry {
- char idstr[256];
- int instance_id;
- int version_id;
- SaveStateHandler *save_state;
- LoadStateHandler *load_state;
- void *opaque;
- struct SaveStateEntry *next;
-} SaveStateEntry;
-
-static SaveStateEntry *first_se;
-
-int register_savevm(const char *idstr,
- int instance_id,
- int version_id,
- SaveStateHandler *save_state,
- LoadStateHandler *load_state,
- void *opaque)
-{
- SaveStateEntry *se, **pse;
-
- se = qemu_malloc(sizeof(SaveStateEntry));
- if (!se)
- return -1;
- pstrcpy(se->idstr, sizeof(se->idstr), idstr);
- se->instance_id = instance_id;
- se->version_id = version_id;
- se->save_state = save_state;
- se->load_state = load_state;
- se->opaque = opaque;
- se->next = NULL;
-
- /* add at the end of list */
- pse = &first_se;
- while (*pse != NULL)
- pse = &(*pse)->next;
- *pse = se;
- return 0;
-}
-
-#define QEMU_VM_FILE_MAGIC 0x5145564d
-#define QEMU_VM_FILE_VERSION 0x00000001
-
-int qemu_savevm(const char *filename)
-{
- SaveStateEntry *se;
- QEMUFile *f;
- int len, len_pos, cur_pos, saved_vm_running, ret;
-
- saved_vm_running = vm_running;
- vm_stop(0);
-
- f = fopen(filename, "wb");
- if (!f) {
- ret = -1;
- goto the_end;
- }
-
- qemu_put_be32(f, QEMU_VM_FILE_MAGIC);
- qemu_put_be32(f, QEMU_VM_FILE_VERSION);
-
- for(se = first_se; se != NULL; se = se->next) {
- /* ID string */
- len = strlen(se->idstr);
- qemu_put_byte(f, len);
- qemu_put_buffer(f, se->idstr, len);
-
- qemu_put_be32(f, se->instance_id);
- qemu_put_be32(f, se->version_id);
-
- /* record size: filled later */
- len_pos = ftell(f);
- qemu_put_be32(f, 0);
-
- se->save_state(f, se->opaque);
-
- /* fill record size */
- cur_pos = ftell(f);
- len = ftell(f) - len_pos - 4;
- fseek(f, len_pos, SEEK_SET);
- qemu_put_be32(f, len);
- fseek(f, cur_pos, SEEK_SET);
- }
-
- fclose(f);
- ret = 0;
- the_end:
- if (saved_vm_running)
- vm_start();
- return ret;
-}
-
-static SaveStateEntry *find_se(const char *idstr, int instance_id)
-{
- SaveStateEntry *se;
-
- for(se = first_se; se != NULL; se = se->next) {
- if (!strcmp(se->idstr, idstr) &&
- instance_id == se->instance_id)
- return se;
- }
- return NULL;
-}
-
-int qemu_loadvm(const char *filename)
-{
- SaveStateEntry *se;
- QEMUFile *f;
- int len, cur_pos, ret, instance_id, record_len, version_id;
- int saved_vm_running;
- unsigned int v;
- char idstr[256];
-
- saved_vm_running = vm_running;
- vm_stop(0);
-
- f = fopen(filename, "rb");
- if (!f) {
- ret = -1;
- goto the_end;
- }
-
- v = qemu_get_be32(f);
- if (v != QEMU_VM_FILE_MAGIC)
- goto fail;
- v = qemu_get_be32(f);
- if (v != QEMU_VM_FILE_VERSION) {
- fail:
- fclose(f);
- ret = -1;
- goto the_end;
- }
- for(;;) {
-#if defined (DO_TB_FLUSH)
- tb_flush(global_env);
-#endif
- len = qemu_get_byte(f);
- if (feof(f))
- break;
- qemu_get_buffer(f, idstr, len);
- idstr[len] = '\0';
- instance_id = qemu_get_be32(f);
- version_id = qemu_get_be32(f);
- record_len = qemu_get_be32(f);
-#if 0
- printf("idstr=%s instance=0x%x version=%d len=%d\n",
- idstr, instance_id, version_id, record_len);
-#endif
- cur_pos = ftell(f);
- se = find_se(idstr, instance_id);
- if (!se) {
- fprintf(stderr, "qemu: warning: instance 0x%x of device '%s' not present in current VM\n",
- instance_id, idstr);
- } else {
- ret = se->load_state(f, se->opaque, version_id);
- if (ret < 0) {
- fprintf(stderr, "qemu: warning: error while loading state for instance 0x%x of device '%s'\n",
- instance_id, idstr);
- }
- }
- /* always seek to exact end of record */
- qemu_fseek(f, cur_pos + record_len, SEEK_SET);
- }
- fclose(f);
- ret = 0;
- the_end:
- if (saved_vm_running)
- vm_start();
- return ret;
-}
-
-/***********************************************************/
-/* main execution loop */
-
-void gui_update(void *opaque)
-{
- display_state.dpy_refresh(&display_state);
- qemu_mod_timer(gui_timer, GUI_REFRESH_INTERVAL + qemu_get_clock(rt_clock));
-}
-void polling_handler(void *opaque)
-{
-#ifndef _WIN32
- struct pollfd ufds[MAX_IO_HANDLERS + 1], *pf;
- IOHandlerRecord *ioh, *ioh_next;
- uint8_t buf[4096];
- int n, max_size;
-#endif
- int timeout = 0;
- int ret;
-
-#ifdef _WIN32
- if (timeout > 0)
- Sleep(timeout);
-#else
- /* poll any events */
- /* XXX: separate device handlers from system ones */
- pf = ufds;
- for(ioh = first_io_handler; ioh != NULL; ioh = ioh->next) {
- if (!ioh->fd_can_read) {
- max_size = 0;
- pf->fd = ioh->fd;
- pf->events = POLLIN;
- ioh->ufd = pf;
- pf++;
- } else {
- max_size = ioh->fd_can_read(ioh->opaque);
- if (max_size > 0) {
- if (max_size > sizeof(buf))
- max_size = sizeof(buf);
- pf->fd = ioh->fd;
- pf->events = POLLIN;
- ioh->ufd = pf;
- pf++;
- } else {
- ioh->ufd = NULL;
- }
- }
- ioh->max_size = max_size;
- }
-
- ret = poll(ufds, pf - ufds, timeout);
- if (ret > 0) {
- /* XXX: better handling of removal */
- for(ioh = first_io_handler; ioh != NULL; ioh = ioh_next) {
- ioh_next = ioh->next;
- pf = ioh->ufd;
- if (pf) {
- if (pf->revents & POLLIN) {
- if (ioh->max_size == 0) {
- /* just a read event */
- ioh->fd_read(ioh->opaque, NULL, 0);
- } else {
- n = read(ioh->fd, buf, ioh->max_size);
- if (n >= 0) {
- ioh->fd_read(ioh->opaque, buf, n);
- } else if (errno != EAGAIN) {
- ioh->fd_read(ioh->opaque, NULL, -errno);
- }
- }
- }
- }
- }
- }
-#endif /* !defined(_WIN32) */
-
- qemu_mod_timer(polling_timer, POLLING_INTERVAL + qemu_get_clock(rt_clock));
-}
-
-
-/* XXX: support several handlers */
-VMStopHandler *vm_stop_cb;
-VMStopHandler *vm_stop_opaque;
-
-int qemu_add_vm_stop_handler(VMStopHandler *cb, void *opaque)
-{
- vm_stop_cb = cb;
- vm_stop_opaque = opaque;
- return 0;
-}
-
-void qemu_del_vm_stop_handler(VMStopHandler *cb, void *opaque)
-{
- vm_stop_cb = NULL;
-}
-
-void vm_start(void)
-{
- if (!vm_running) {
- cpu_enable_ticks();
- vm_running = 1;
- }
-}
-
-void vm_stop(int reason)
-{
- if (vm_running) {
- cpu_disable_ticks();
- vm_running = 0;
- if (reason != 0) {
- if (vm_stop_cb) {
- vm_stop_cb(vm_stop_opaque, reason);
- }
- }
- }
-}
-
-/* reset/shutdown handler */
-
-typedef struct QEMUResetEntry {
- QEMUResetHandler *func;
- void *opaque;
- struct QEMUResetEntry *next;
-} QEMUResetEntry;
-
-static QEMUResetEntry *first_reset_entry;
-int reset_requested;
-int shutdown_requested;
-
-void qemu_register_reset(QEMUResetHandler *func, void *opaque)
-{
- QEMUResetEntry **pre, *re;
-
- pre = &first_reset_entry;
- while (*pre != NULL)
- pre = &(*pre)->next;
- re = qemu_mallocz(sizeof(QEMUResetEntry));
- re->func = func;
- re->opaque = opaque;
- re->next = NULL;
- *pre = re;
-}
-
-void qemu_system_reset(void)
-{
- QEMUResetEntry *re;
-
- /* reset all devices */
- for(re = first_reset_entry; re != NULL; re = re->next) {
- re->func(re->opaque);
- }
-}
-
-void qemu_system_reset_request(void)
-{
- reset_requested = 1;
- cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT);
-}
-
-void qemu_system_shutdown_request(void)
-{
- shutdown_requested = 1;
- cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT);
-}
-
-void main_loop_wait(int timeout)
-{
- if (vm_running) {
- qemu_run_timers(&active_timers[QEMU_TIMER_VIRTUAL],
- qemu_get_clock(vm_clock));
- /* run dma transfers, if any */
- DMA_run();
- }
-
- /* real time timers */
- qemu_run_timers(&active_timers[QEMU_TIMER_REALTIME],
- qemu_get_clock(rt_clock));
-}
-
-void help(void)
-{
- printf("QEMU PC emulator version " QEMU_VERSION ", Copyright (c) 2003-2004 Fabrice Bellard\n"
- "usage: %s [options] [disk_image]\n"
- "\n"
- "'disk_image' is a raw hard image image for IDE hard disk 0\n"
- "\n"
- "Standard options:\n"
- "-fda/-fdb file use 'file' as floppy disk 0/1 image\n"
- "-hda/-hdb file use 'file' as IDE hard disk 0/1 image\n"
- "-hdc/-hdd file use 'file' as IDE hard disk 2/3 image\n"
- "-cdrom file use 'file' as IDE cdrom image (cdrom is ide1 master)\n"
- "-boot [a|c|d] boot on floppy (a), hard disk (c) or CD-ROM (d)\n"
- "-snapshot write to temporary files instead of disk image files\n"
- "-m megs set virtual RAM size to megs MB [default=%d]\n"
- "-nographic disable graphical output and redirect serial I/Os to console\n"
- "-vcpus set CPU number of guest platform\n"
-#ifdef CONFIG_VNC
- "-vnc port use vnc instead of sdl\n"
- "-vncport port use a different port\n"
- "-vncconnect host:port do a reverse connect\n"
-#ifdef CONFIG_SDL
- "-vnc-and-sdl use vnc and sdl simultaneously\n"
-#endif
-#endif
- "-k <language> use keyboard layout (for example \"fr\" for french)\n"
- "-enable-audio enable audio support\n"
- "-localtime set the real time clock to local time [default=utc]\n"
- "-full-screen start in full screen\n"
- "-usb enable the USB driver (will be the default soon)\n"
- "-usbdevice name add the host or guest USB device 'name'\n"
-#ifdef TARGET_PPC
- "-prep Simulate a PREP system (default is PowerMAC)\n"
- "-g WxH[xDEPTH] Set the initial VGA graphic mode\n"
-#endif
- "-nic-ne2000 simulate an Realtek ne2k PCI ethernet adaptor\n"
- "\n"
- "Network options:\n"
- "-nics n simulate 'n' network cards [default=1]\n"
- "-macaddr addr set the mac address of the first interface\n"
- "-bridge br set the bridge interface for nic\n"
- "-n script set tap/tun network init script [default=%s]\n"
- "-tun-fd fd use this fd as already opened tap/tun interface\n"
-#ifdef CONFIG_SLIRP
- "-user-net use user mode network stack [default if no tap/tun script]\n"
- "-tftp prefix allow tftp access to files starting with prefix [-user-net]\n"
-#ifndef _WIN32
- "-smb dir allow SMB access to files in 'dir' [-user-net]\n"
-#endif
- "-redir [tcp|udp]:host-port:[guest-host]:guest-port\n"
- " redirect TCP or UDP connections from host to guest [-user-net]\n"
-#endif
- "-dummy-net use dummy network stack\n"
- "\n"
- "Linux boot specific:\n"
- "-kernel bzImage use 'bzImage' as kernel image\n"
- "-append cmdline use 'cmdline' as kernel command line\n"
- "-initrd file use 'file' as initial ram disk\n"
- "\n"
- "Debug/Expert options:\n"
- "-monitor dev redirect the monitor to char device 'dev'\n"
- "-serial dev redirect the serial port to char device 'dev'\n"
- "-S freeze CPU at startup (use 'c' to start execution)\n"
- "-s wait gdb connection to port %d\n"
- "-p port ioreq port for xen\n"
- "-d domain domain that we're serving\n"
- "-domain-name domain name that we're serving\n"
- "-hdachs c,h,s force hard disk 0 geometry (usually qemu can guess it)\n"
- "-L path set the directory for the BIOS and VGA BIOS\n"
- "-timeoffset time offset (in seconds) from local time (Xen)\n"
-#ifdef USE_CODE_COPY
- "-no-code-copy disable code copy acceleration\n"
-#endif
-#ifdef TARGET_I386
- "-isa simulate an ISA-only system (default is PCI system)\n"
- "-std-vga simulate a standard VGA card with VESA Bochs Extensions\n"
- " (default is CL-GD5446 PCI VGA)\n"
- "-vgaacc [0|1] 1 to accelerate CL-GD5446 speed, default is 1\n"
- "-no-repeatkey disable key repeat feature for SDL keyboard simulation"
-#endif
- "-loadvm file start right away with a saved state (loadvm in monitor)\n"
- "\n"
- "During emulation, the following keys are useful:\n"
- "ctrl-alt-f toggle full screen\n"
- "ctrl-alt-n switch to virtual console 'n'\n"
- "ctrl-alt toggle mouse and keyboard grab\n"
- "\n"
- "When using -nographic, press 'ctrl-a h' to get some help.\n"
- ,
-#ifdef CONFIG_SOFTMMU
- "qemu",
-#else
- "qemu-fast",
-#endif
- DEFAULT_RAM_SIZE,
- DEFAULT_NETWORK_SCRIPT,
- DEFAULT_GDBSTUB_PORT);
-#ifndef CONFIG_SOFTMMU
- printf("\n"
- "NOTE: this version of QEMU is faster but it needs slightly patched OSes to\n"
- "work. Please use the 'qemu' executable to have a more accurate (but slower)\n"
- "PC emulation.\n");
-#endif
- exit(1);
-}
-
-#define HAS_ARG 0x0001
-
-enum {
- QEMU_OPTION_h,
-
- QEMU_OPTION_fda,
- QEMU_OPTION_fdb,
- QEMU_OPTION_hda,
- QEMU_OPTION_hdb,
- QEMU_OPTION_hdc,
- QEMU_OPTION_hdd,
- QEMU_OPTION_cdrom,
- QEMU_OPTION_boot,
- QEMU_OPTION_snapshot,
- QEMU_OPTION_m,
- QEMU_OPTION_nographic,
-#ifdef CONFIG_VNC
- QEMU_OPTION_vnc,
- QEMU_OPTION_vncport,
- QEMU_OPTION_vncconnect,
-#ifdef CONFIG_SDL
- QEMU_OPTION_vnc_and_sdl,
-#endif
-#endif
- QEMU_OPTION_enable_audio,
-
- QEMU_OPTION_nics,
- QEMU_OPTION_macaddr,
- QEMU_OPTION_bridge,
- QEMU_OPTION_n,
- QEMU_OPTION_tun_fd,
- QEMU_OPTION_user_net,
- QEMU_OPTION_tftp,
- QEMU_OPTION_smb,
- QEMU_OPTION_redir,
- QEMU_OPTION_dummy_net,
-
- QEMU_OPTION_kernel,
- QEMU_OPTION_append,
- QEMU_OPTION_initrd,
-
- QEMU_OPTION_S,
- QEMU_OPTION_s,
- QEMU_OPTION_d,
- QEMU_OPTION_l,
- QEMU_OPTION_hdachs,
- QEMU_OPTION_L,
- QEMU_OPTION_no_code_copy,
- QEMU_OPTION_vcpus,
- QEMU_OPTION_pci,
- QEMU_OPTION_nic_ne2000,
- QEMU_OPTION_isa,
- QEMU_OPTION_prep,
- QEMU_OPTION_k,
- QEMU_OPTION_localtime,
- QEMU_OPTION_cirrusvga,
- QEMU_OPTION_g,
- QEMU_OPTION_std_vga,
- QEMU_OPTION_monitor,
- QEMU_OPTION_domainname,
- QEMU_OPTION_serial,
- QEMU_OPTION_timeoffset,
- QEMU_OPTION_loadvm,
- QEMU_OPTION_full_screen,
- QEMU_OPTION_vgaacc,
- QEMU_OPTION_repeatkey,
- QEMU_OPTION_usb,
- QEMU_OPTION_usbdevice,
-};
-
-typedef struct QEMUOption {
- const char *name;
- int flags;
- int index;
-} QEMUOption;
-
-const QEMUOption qemu_options[] = {
- { "h", 0, QEMU_OPTION_h },
-
- { "fda", HAS_ARG, QEMU_OPTION_fda },
- { "fdb", HAS_ARG, QEMU_OPTION_fdb },
- { "hda", HAS_ARG, QEMU_OPTION_hda },
- { "hdb", HAS_ARG, QEMU_OPTION_hdb },
- { "hdc", HAS_ARG, QEMU_OPTION_hdc },
- { "hdd", HAS_ARG, QEMU_OPTION_hdd },
- { "cdrom", HAS_ARG, QEMU_OPTION_cdrom },
- { "boot", HAS_ARG, QEMU_OPTION_boot },
- { "snapshot", 0, QEMU_OPTION_snapshot },
- { "m", HAS_ARG, QEMU_OPTION_m },
- { "nographic", 0, QEMU_OPTION_nographic },
-#ifdef CONFIG_VNC
- { "vnc", 0, QEMU_OPTION_vnc },
- { "vncport", HAS_ARG, QEMU_OPTION_vncport },
- { "vncconnect", HAS_ARG, QEMU_OPTION_vncconnect },
-#ifdef CONFIG_SDL
- { "vnc-and-sdl", 0, QEMU_OPTION_vnc_and_sdl },
-#endif
-#endif
- { "k", HAS_ARG, QEMU_OPTION_k },
- { "enable-audio", 0, QEMU_OPTION_enable_audio },
-
- { "nics", HAS_ARG, QEMU_OPTION_nics},
- { "macaddr", HAS_ARG, QEMU_OPTION_macaddr},
- { "bridge", HAS_ARG, QEMU_OPTION_bridge},
- { "n", HAS_ARG, QEMU_OPTION_n },
- { "tun-fd", HAS_ARG, QEMU_OPTION_tun_fd },
-#ifdef CONFIG_SLIRP
- { "user-net", 0, QEMU_OPTION_user_net },
- { "tftp", HAS_ARG, QEMU_OPTION_tftp },
-#ifndef _WIN32
- { "smb", HAS_ARG, QEMU_OPTION_smb },
-#endif
- { "redir", HAS_ARG, QEMU_OPTION_redir },
-#endif
- { "dummy-net", 0, QEMU_OPTION_dummy_net },
-
- { "kernel", HAS_ARG, QEMU_OPTION_kernel },
- { "append", HAS_ARG, QEMU_OPTION_append },
- { "initrd", HAS_ARG, QEMU_OPTION_initrd },
-
- { "S", 0, QEMU_OPTION_S },
- { "s", 0, QEMU_OPTION_s },
- { "d", HAS_ARG, QEMU_OPTION_d },
- { "l", HAS_ARG, QEMU_OPTION_l },
- { "hdachs", HAS_ARG, QEMU_OPTION_hdachs },
- { "L", HAS_ARG, QEMU_OPTION_L },
- { "no-code-copy", 0, QEMU_OPTION_no_code_copy },
- { "vcpus", 1, QEMU_OPTION_vcpus },
-#ifdef TARGET_PPC
- { "prep", 0, QEMU_OPTION_prep },
- { "g", 1, QEMU_OPTION_g },
-#endif
- { "localtime", 0, QEMU_OPTION_localtime },
- { "isa", 0, QEMU_OPTION_isa },
- { "std-vga", 0, QEMU_OPTION_std_vga },
- { "monitor", 1, QEMU_OPTION_monitor },
- { "domain-name", 1, QEMU_OPTION_domainname },
- { "timeoffset", HAS_ARG, QEMU_OPTION_timeoffset },
- { "serial", 1, QEMU_OPTION_serial },
- { "loadvm", HAS_ARG, QEMU_OPTION_loadvm },
- { "full-screen", 0, QEMU_OPTION_full_screen },
- { "usbdevice", HAS_ARG, QEMU_OPTION_usbdevice },
-
- /* temporary options */
- { "usb", 0, QEMU_OPTION_usb },
- { "pci", 0, QEMU_OPTION_pci },
- { "nic-ne2000", 0, QEMU_OPTION_nic_ne2000 },
- { "cirrusvga", 0, QEMU_OPTION_cirrusvga },
- { "vgaacc", HAS_ARG, QEMU_OPTION_vgaacc },
- { "no-repeatkey", 0, QEMU_OPTION_repeatkey },
- { NULL },
-};
-
-#if defined (TARGET_I386) && defined(USE_CODE_COPY)
-
-/* this stack is only used during signal handling */
-#define SIGNAL_STACK_SIZE 32768
-
-static uint8_t *signal_stack;
-
-#endif
-
-#define NET_IF_TUN 0
-#define NET_IF_USER 1
-#define NET_IF_DUMMY 2
-
-#include <xg_private.h>
-
-/* FIXME Flush the shadow page */
-int unset_mm_mapping(int xc_handle,
- uint32_t domid,
- unsigned long nr_pages,
- unsigned int address_bits,
- xen_pfn_t *extent_start)
-{
- int err = 0;
- xc_dominfo_t info;
-
- err = xc_domain_memory_decrease_reservation(xc_handle, domid,
- nr_pages, 0, extent_start);
-
- if ( err )
- fprintf(stderr, "Failed to decrease physmap\n");
-
- xc_domain_getinfo(xc_handle, domid, 1, &info);
-
- if ( (info.nr_pages - nr_pages) <= 0 )
- {
- fprintf(stderr, "unset_mm_mapping: error nr_pages\n");
- err = -1;
- }
-
- if ( xc_domain_setmaxmem(xc_handle, domid,
- (info.nr_pages - nr_pages) * PAGE_SIZE/1024) != 0)
- {
- fprintf(logfile, "set maxmem returned error %d\n", errno);
- err = -1;
- }
-
- return err;
-}
-
-int set_mm_mapping(int xc_handle,
- uint32_t domid,
- unsigned long nr_pages,
- unsigned int address_bits,
- xen_pfn_t *extent_start)
-{
- xc_dominfo_t info;
- int err = 0;
-
- xc_domain_getinfo(xc_handle, domid, 1, &info);
-
- if ( xc_domain_setmaxmem(xc_handle, domid,
- info.max_memkb + nr_pages * PAGE_SIZE/1024) !=0)
- {
- fprintf(logfile, "set maxmem returned error %d\n", errno);
- return -1;
- }
-
- err = xc_domain_memory_populate_physmap(xc_handle, domid,
- nr_pages, 0,
- address_bits, extent_start);
-
- if ( err )
- {
- fprintf(stderr, "Failed to populate physmap\n");
- return -1;
- }
-
- err = xc_domain_translate_gpfn_list(xc_handle, domid,
- nr_pages,
- extent_start, extent_start);
-
- if ( err )
- {
- fprintf(stderr, "Failed to translate gpfn list\n");
- return -1;
- }
-
-#if 0 /* Generates lots of log file output - turn on for debugging */
- for (i = 0; i < nr_pages; i++)
- fprintf(stderr, "set_map result i %x result %lx\n", i, extent_start[i]);
-#endif
-
- return 0;
-}
-
-int main(int argc, char **argv)
-{
-#ifdef CONFIG_GDBSTUB
- int use_gdbstub, gdbstub_port;
-#endif
- int i, has_cdrom;
- int snapshot, linux_boot;
- CPUState *env;
- const char *initrd_filename;
- const char *hd_filename[MAX_DISKS], *fd_filename[MAX_FD];
- const char *kernel_filename, *kernel_cmdline;
- DisplayState *ds = &display_state;
- int cyls, heads, secs;
- int start_emulation = 1;
- uint8_t macaddr[6];
- int net_if_type, nb_tun_fds, tun_fds[MAX_NICS];
- int optind;
- const char *r, *optarg;
- CharDriverState *monitor_hd;
- char monitor_device[128];
- char serial_devices[MAX_SERIAL_PORTS][128];
- int serial_device_index;
- char usb_devices[MAX_VM_USB_PORTS][128];
- int usb_devices_index;
- char qemu_dm_logfilename[64];
- const char *loadvm = NULL;
- unsigned long nr_pages;
- xen_pfn_t *page_array;
- extern void *shared_page;
-
-#if !defined(CONFIG_SOFTMMU)
- /* we never want that malloc() uses mmap() */
- mallopt(M_MMAP_THRESHOLD, 4096 * 1024);
-#endif
- initrd_filename = NULL;
- for(i = 0; i < MAX_FD; i++)
- fd_filename[i] = NULL;
- for(i = 0; i < MAX_DISKS; i++)
- hd_filename[i] = NULL;
- ram_size = DEFAULT_RAM_SIZE * 1024 * 1024;
- vga_ram_size = VGA_RAM_SIZE;
- bios_size = BIOS_SIZE;
- pstrcpy(network_script, sizeof(network_script), DEFAULT_NETWORK_SCRIPT);
-#ifdef CONFIG_GDBSTUB
- use_gdbstub = 0;
- gdbstub_port = DEFAULT_GDBSTUB_PORT;
-#endif
- snapshot = 0;
- nographic = 0;
- usevnc = 0;
- vncport=0;
- vncconnect=NULL;
- kernel_filename = NULL;
- kernel_cmdline = "";
- has_cdrom = 1;
- cyls = heads = secs = 0;
- pstrcpy(monitor_device, sizeof(monitor_device), "vc");
-
- pstrcpy(serial_devices[0], sizeof(serial_devices[0]), "vc");
- serial_summa_port = -1;
- for(i = 1; i < MAX_SERIAL_PORTS; i++)
- serial_devices[i][0] = '\0';
- serial_device_index = 0;
-
- usb_devices_index = 0;
- nb_tun_fds = 0;
- net_if_type = -1;
- nb_nics = 1;
- /* default mac address of the first network interface */
- macaddr[0] = 0x52;
- macaddr[1] = 0x54;
- macaddr[2] = 0x00;
- macaddr[3] = 0x12;
- macaddr[4] = 0x34;
- macaddr[5] = 0x56;
-
- /* init debug */
- sprintf(qemu_dm_logfilename, "/var/log/qemu-dm.%d.log", getpid());
- cpu_set_log_filename(qemu_dm_logfilename);
- cpu_set_log(0);
-
- optind = 1;
- for(;;) {
- if (optind >= argc)
- break;
- r = argv[optind];
- if (r[0] != '-') {
- hd_filename[0] = argv[optind++];
- } else {
- const QEMUOption *popt;
-
- optind++;
- popt = qemu_options;
- for(;;) {
- if (!popt->name) {
- fprintf(stderr, "%s: invalid option -- '%s'\n",
- argv[0], r);
- exit(1);
- }
- if (!strcmp(popt->name, r + 1))
- break;
- popt++;
- }
- if (popt->flags & HAS_ARG) {
- if (optind >= argc) {
- fprintf(stderr, "%s: option '%s' requires an argument\n",
- argv[0], r);
- exit(1);
- }
- optarg = argv[optind++];
- } else {
- optarg = NULL;
- }
-
- switch(popt->index) {
- case QEMU_OPTION_initrd:
- initrd_filename = optarg;
- break;
- case QEMU_OPTION_hda:
- hd_filename[0] = optarg;
- break;
- case QEMU_OPTION_hdb:
- hd_filename[1] = optarg;
- break;
- case QEMU_OPTION_snapshot:
- snapshot = 1;
- break;
- case QEMU_OPTION_hdachs:
- {
- const char *p;
- p = optarg;
- cyls = strtol(p, (char **)&p, 0);
- if (*p != ',')
- goto chs_fail;
- p++;
- heads = strtol(p, (char **)&p, 0);
- if (*p != ',')
- goto chs_fail;
- p++;
- secs = strtol(p, (char **)&p, 0);
- if (*p != '\0') {
- chs_fail:
- cyls = 0;
- }
- }
- break;
- case QEMU_OPTION_nographic:
- pstrcpy(monitor_device, sizeof(monitor_device), "stdio");
- if(!strcmp(serial_devices[0], "vc"))
- pstrcpy(serial_devices[0], sizeof(serial_devices[0]),
- "stdio");
- nographic = 1;
- break;
-#ifdef CONFIG_VNC
- case QEMU_OPTION_vnc:
- usevnc = 1;
- break;
- case QEMU_OPTION_vncport:
- {
- const char *p;
- p = optarg;
- vncport= strtol(optarg, (char **)&p, 0);
- }
- break;
- case QEMU_OPTION_vncconnect:
- vncconnect = optarg;
- break;
-#ifdef CONFIG_SDL
- case QEMU_OPTION_vnc_and_sdl:
- usevnc = 2;
- break;
-#endif
-#endif
- case QEMU_OPTION_kernel:
- kernel_filename = optarg;
- break;
- case QEMU_OPTION_append:
- kernel_cmdline = optarg;
- break;
- case QEMU_OPTION_tun_fd:
- {
- const char *p;
- int fd;
- net_if_type = NET_IF_TUN;
- if ( nb_tun_fds < MAX_NICS ) {
- fd = strtol(optarg, (char **)&p, 0);
- if (*p != '\0') {
- fprintf(stderr,
- "qemu: invalid fd for network interface %d\n",
- nb_tun_fds);
- exit(1);
- }
- tun_fds[nb_tun_fds++] = fd;
- }
- }
- break;
- case QEMU_OPTION_hdc:
- hd_filename[2] = optarg;
- has_cdrom = 0;
- break;
- case QEMU_OPTION_hdd:
- hd_filename[3] = optarg;
- break;
- case QEMU_OPTION_cdrom:
- hd_filename[2] = optarg;
- has_cdrom = 1;
- break;
- case QEMU_OPTION_boot:
- boot_device = optarg[0];
- if ( boot_device != 'a' &&
- boot_device != 'c' &&
- boot_device != 'd' ) {
- fprintf(stderr, "qemu: invalid boot device '%c'\n",
- boot_device);
- exit(1);
- }
- break;
- case QEMU_OPTION_fda:
- fd_filename[0] = optarg;
- break;
- case QEMU_OPTION_fdb:
- fd_filename[1] = optarg;
- break;
- case QEMU_OPTION_nics:
- nb_nics = atoi(optarg);
- if (nb_nics < 0 || nb_nics > MAX_NICS) {
- fprintf(stderr,
- "qemu: invalid number of network interfaces\n");
- exit(1);
- }
- break;
- case QEMU_OPTION_bridge:
- pstrcpy(bridge, sizeof(bridge), optarg);
- break;
- case QEMU_OPTION_macaddr:
- {
- const char *p;
- int i;
-
- p = optarg;
- for (i = 0; i < 6; i++) {
- macaddr[i] = strtol(p, (char **)&p, 16);
- if (i == 5) {
- if (*p != '\0')
- goto macaddr_error;
- } else {
- if (*p != ':') {
- macaddr_error:
- fprintf(stderr, "qemu: invalid syntax "
- "for ethernet address\n");
- exit(1);
- }
- p++;
- }
- }
- }
- break;
-#ifdef CONFIG_SLIRP
- case QEMU_OPTION_tftp:
- tftp_prefix = optarg;
- break;
-#ifndef _WIN32
- case QEMU_OPTION_smb:
- net_slirp_smb(optarg);
- break;
-#endif
- case QEMU_OPTION_user_net:
- net_if_type = NET_IF_USER;
- break;
- case QEMU_OPTION_redir:
- net_slirp_redir(optarg);
- break;
-#endif
- case QEMU_OPTION_dummy_net:
- net_if_type = NET_IF_DUMMY;
- break;
- case QEMU_OPTION_enable_audio:
- audio_enabled = 1;
- break;
- case QEMU_OPTION_h:
- help();
- break;
- case QEMU_OPTION_m:
- ram_size = atol(optarg) * 1024 * 1024;
- if (ram_size <= 0)
- help();
- break;
- case QEMU_OPTION_d:
- {
- domid = atoi(optarg);
- fprintf(logfile, "domid: %d\n", domid);
- }
- break;
- case QEMU_OPTION_l:
- {
- int mask;
- mask = cpu_str_to_log_mask(optarg);
- fprintf(logfile, "mask: %x\n", mask);
- cpu_set_log(mask);
- }
- break;
- case QEMU_OPTION_n:
- pstrcpy(network_script, sizeof(network_script), optarg);
- break;
-#ifdef CONFIG_GDBSTUB
- case QEMU_OPTION_s:
- use_gdbstub = 1;
- break;
-#endif
- case QEMU_OPTION_L:
- bios_dir = optarg;
- break;
- case QEMU_OPTION_S:
- start_emulation = 0;
- break;
- case QEMU_OPTION_vcpus:
- vcpus = atoi(optarg);
- fprintf(logfile, "qemu: the number of cpus is %d\n", vcpus);
- break;
- case QEMU_OPTION_pci:
- pci_enabled = 1;
- break;
- case QEMU_OPTION_nic_ne2000:
- nic_ne2000 = 1;
- break;
- case QEMU_OPTION_isa:
- pci_enabled = 0;
- break;
- case QEMU_OPTION_prep:
- prep_enabled = 1;
- break;
- case QEMU_OPTION_k:
- keyboard_layout = optarg;
- break;
- case QEMU_OPTION_localtime:
- rtc_utc = 0;
- break;
- case QEMU_OPTION_cirrusvga:
- cirrus_vga_enabled = 1;
- break;
- case QEMU_OPTION_vgaacc:
- {
- const char *p;
- p = optarg;
- vga_accelerate = strtol(p, (char **)&p, 0);
- if (*p != '\0') {
- fprintf(stderr, "qemu: invalid vgaacc option\n");
- exit(1);
- }
- }
- break;
- case QEMU_OPTION_repeatkey:
- repeat_key = 0;
- break;
- case QEMU_OPTION_std_vga:
- cirrus_vga_enabled = 0;
- break;
- case QEMU_OPTION_g:
- {
- const char *p;
- int w, h, depth;
- p = optarg;
- w = strtol(p, (char **)&p, 10);
- if (w <= 0) {
- graphic_error:
- fprintf(stderr, "qemu: invalid resolution or depth\n");
- exit(1);
- }
- if (*p != 'x')
- goto graphic_error;
- p++;
- h = strtol(p, (char **)&p, 10);
- if (h <= 0)
- goto graphic_error;
- if (*p == 'x') {
- p++;
- depth = strtol(p, (char **)&p, 10);
- if (depth != 8 && depth != 15 && depth != 16 &&
- depth != 24 && depth != 32)
- goto graphic_error;
- } else if (*p == '\0') {
- depth = graphic_depth;
- } else {
- goto graphic_error;
- }
-
- graphic_width = w;
- graphic_height = h;
- graphic_depth = depth;
- }
- break;
- case QEMU_OPTION_monitor:
- pstrcpy(monitor_device, sizeof(monitor_device), optarg);
- break;
- case QEMU_OPTION_serial:
- if (serial_device_index >= MAX_SERIAL_PORTS) {
- fprintf(stderr, "qemu: too many serial ports\n");
- exit(1);
- }
- pstrcpy(serial_devices[serial_device_index],
- sizeof(serial_devices[0]), optarg);
- serial_device_index++;
- break;
- case QEMU_OPTION_loadvm:
- loadvm = optarg;
- break;
- case QEMU_OPTION_full_screen:
- full_screen = 1;
- break;
- case QEMU_OPTION_usb:
- usb_enabled = 1;
- break;
- case QEMU_OPTION_usbdevice:
- usb_enabled = 1;
- if (usb_devices_index >= MAX_VM_USB_PORTS) {
- fprintf(stderr, "Too many USB devices\n");
- exit(1);
- }
- pstrcpy(usb_devices[usb_devices_index],
- sizeof(usb_devices[usb_devices_index]),
- optarg);
- usb_devices_index++;
- break;
- case QEMU_OPTION_domainname:
- strncat(domain_name, optarg, sizeof(domain_name) - 20);
- break;
- case QEMU_OPTION_timeoffset:
- timeoffset = strtol(optarg, NULL, 0);
- break;
-
- }
- }
- }
-
- linux_boot = (kernel_filename != NULL);
-
- if ( !linux_boot && hd_filename[0] == '\0' &&
- hd_filename[2] == '\0' && fd_filename[0] == '\0' )
- help();
-
- /* boot to cd by default if no hard disk */
- if (hd_filename[0] == '\0' && boot_device == 'c') {
- if (fd_filename[0] != '\0')
- boot_device = 'a';
- else
- boot_device = 'd';
- }
-
-#if !defined(CONFIG_SOFTMMU)
- /* must avoid mmap() usage of glibc by setting a buffer "by hand" */
- {
- static uint8_t stdout_buf[4096];
- setvbuf(stdout, stdout_buf, _IOLBF, sizeof(stdout_buf));
- }
-#else
- setvbuf(stdout, NULL, _IOLBF, 0);
-#endif
-
- /* init host network redirectors */
- if (net_if_type == -1) {
- net_if_type = NET_IF_TUN;
-#if defined(CONFIG_SLIRP)
- if (access(network_script, R_OK) < 0) {
- net_if_type = NET_IF_USER;
- }
-#endif
- }
-
- for(i = 0; i < nb_nics; i++) {
- NetDriverState *nd = &nd_table[i];
- nd->index = i;
- /* init virtual mac address */
- nd->macaddr[0] = macaddr[0];
- nd->macaddr[1] = macaddr[1];
- nd->macaddr[2] = macaddr[2];
- nd->macaddr[3] = macaddr[3];
- nd->macaddr[4] = macaddr[4];
- nd->macaddr[5] = macaddr[5] + i;
- switch(net_if_type) {
-#if defined(CONFIG_SLIRP)
- case NET_IF_USER:
- net_slirp_init(nd);
- break;
-#endif
-#if !defined(_WIN32)
- case NET_IF_TUN:
- if (i < nb_tun_fds) {
- net_fd_init(nd, tun_fds[i]);
- } else {
- if (net_tun_init(nd) < 0)
- net_dummy_init(nd);
- }
- break;
-#endif
- case NET_IF_DUMMY:
- default:
- net_dummy_init(nd);
- break;
- }
- }
-
- /* init the memory */
- phys_ram_size = ram_size + vga_ram_size + bios_size;
-
- nr_pages = ram_size/PAGE_SIZE;
-
- xc_handle = xc_interface_open();
-
- if ( (page_array = (xen_pfn_t *)
- malloc(nr_pages * sizeof(xen_pfn_t))) == NULL)
- {
- fprintf(logfile, "malloc returned error %d\n", errno);
- exit(-1);
- }
-
-#if defined(__i386__) || defined(__x86_64__)
- if ( xc_get_pfn_list(xc_handle, domid, page_array, nr_pages) != nr_pages )
- {
- fprintf(logfile, "xc_get_pfn_list returned error %d\n", errno);
- exit(-1);
- }
- if ( (phys_ram_base = xc_map_foreign_batch(xc_handle, domid,
- PROT_READ|PROT_WRITE,
- page_array,
- nr_pages - 1)) == 0 )
- {
- fprintf(logfile, "xc_map_foreign_batch returned error %d\n", errno);
- exit(-1);
- }
-
- shared_page = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE,
- PROT_READ|PROT_WRITE,
- page_array[nr_pages - 1]);
-
-#elif defined(__ia64__)
- if ( xc_ia64_get_pfn_list(xc_handle, domid, page_array, 0, nr_pages)
- != nr_pages)
- {
- fprintf(logfile, "xc_ia64_get_pfn_list returned error %d\n", errno);
- exit(-1);
- }
-
- if ( (phys_ram_base = xc_map_foreign_batch(xc_handle, domid,
- PROT_READ|PROT_WRITE,
- page_array,
- nr_pages)) == 0 )
- {
- fprintf(logfile, "xc_map_foreign_batch returned error %d\n", errno);
- exit(-1);
- }
-
- if ( xc_ia64_get_pfn_list(xc_handle, domid,
- page_array,
- nr_pages + (GFW_SIZE >> PAGE_SHIFT), 1) != 1 )
- {
- fprintf(logfile, "xc_ia64_get_pfn_list returned error %d\n", errno);
- exit(-1);
- }
-
- shared_page = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE,
- PROT_READ|PROT_WRITE,
- page_array[0]);
-#endif
-
- fprintf(logfile, "shared page at pfn:%lx, mfn: %"PRIx64"\n", (nr_pages-1),
- (uint64_t)(page_array[nr_pages - 1]));
-
- /* we always create the cdrom drive, even if no disk is there */
- bdrv_init();
- if (has_cdrom) {
- int fd;
- if ( (fd = open(hd_filename[2], O_RDONLY | O_BINARY)) < 0) {
- hd_filename[2]=NULL;
- bs_table[2]=NULL;
- fprintf(logfile, "Could not open CD %s.\n", hd_filename[i]);
- }
- else {
- close(fd);
- bs_table[2] = bdrv_new("cdrom");
- bdrv_set_type_hint(bs_table[2], BDRV_TYPE_CDROM);
- }
- }
-
- /* open the virtual block devices */
- for(i = 0; i < MAX_DISKS; i++) {
- if (hd_filename[i]) {
- if (!bs_table[i]) {
- char buf[64];
- snprintf(buf, sizeof(buf), "hd%c", i + 'a');
- bs_table[i] = bdrv_new(buf);
- }
- if (bdrv_open(bs_table[i], hd_filename[i], snapshot) < 0) {
- fprintf(stderr, "qemu: could not open hard disk image '%s'\n",
- hd_filename[i]);
- exit(1);
- }
- if (i == 0 && cyls != 0)
- bdrv_set_geometry_hint(bs_table[i], cyls, heads, secs);
- }
- }
-
- /* we always create at least one floppy disk */
- fd_table[0] = bdrv_new("fda");
- bdrv_set_type_hint(fd_table[0], BDRV_TYPE_FLOPPY);
-
- for(i = 0; i < MAX_FD; i++) {
- if (fd_filename[i]) {
- if (!fd_table[i]) {
- char buf[64];
- snprintf(buf, sizeof(buf), "fd%c", i + 'a');
- fd_table[i] = bdrv_new(buf);
- bdrv_set_type_hint(fd_table[i], BDRV_TYPE_FLOPPY);
- }
- if (fd_filename[i] != '\0') {
- if (bdrv_open(fd_table[i], fd_filename[i], snapshot) < 0) {
- fprintf(stderr, "qemu: could not open floppy disk image '%s'\n",
- fd_filename[i]);
- exit(1);
- }
- }
- }
- }
-
- /* init USB devices */
- if (usb_enabled) {
- vm_usb_hub = usb_hub_init(vm_usb_ports, MAX_VM_USB_PORTS);
- for(i = 0; i < usb_devices_index; i++) {
- if (usb_device_add(usb_devices[i]) < 0) {
- fprintf(stderr, "Warning: could not add USB device %s\n",
- usb_devices[i]);
- }
- }
- }
-
- /* init CPU state */
- env = cpu_init();
- global_env = env;
- cpu_single_env = env;
-
- init_ioports();
- cpu_calibrate_ticks();
-
- /* terminal init */
- if (nographic) {
- dumb_display_init(ds);
- } else {
- if (usevnc) {
-#ifdef CONFIG_VNC
- vnc_display_init(ds, (usevnc==2), vncport, vncconnect);
-#else
- fprintf(logfile, "qemu not configured with vnc support\n");
-#endif
- } else {
-#ifdef CONFIG_SDL
- sdl_display_init(ds, full_screen);
-#else
- dumb_display_init(ds);
-#endif
- }
- }
-
- vga_console = graphic_console_init(ds);
-
- monitor_hd = qemu_chr_open(monitor_device);
- if (!monitor_hd) {
- fprintf(stderr, "qemu: could not open monitor device '%s'\n", monitor_device);
- exit(1);
- }
- monitor_init(monitor_hd, !nographic);
-
- /* Find which port should be the Summagraphics port */
- /* It's the first unspecified serial line. Note that COM1 is set */
- /* by default, so the Summagraphics port would be COM2 or higher */
-
- for(i = 0; i < MAX_SERIAL_PORTS; i++) {
- if (serial_devices[i][0] != '\0')
- continue;
- serial_summa_port = i;
- pstrcpy(serial_devices[serial_summa_port], sizeof(serial_devices[0]), "null");
- break;
- }
-
- /* Now, open the ports */
-
- for(i = 0; i < MAX_SERIAL_PORTS; i++) {
- if (serial_devices[i][0] != '\0') {
- serial_hds[i] = qemu_chr_open(serial_devices[i]);
- if (!serial_hds[i]) {
- fprintf(stderr, "qemu: could not open serial device '%s'\n",
- serial_devices[i]);
- exit(1);
- }
- if (!strcmp(serial_devices[i], "vc"))
- qemu_chr_printf(serial_hds[i], "serial%d console\n", i);
- }
- }
-
- /* setup cpu signal handlers for MMU / self modifying code handling */
-#if !defined(CONFIG_SOFTMMU)
-
-#if defined (TARGET_I386) && defined(USE_CODE_COPY)
- {
- stack_t stk;
- signal_stack = memalign(16, SIGNAL_STACK_SIZE);
- stk.ss_sp = signal_stack;
- stk.ss_size = SIGNAL_STACK_SIZE;
- stk.ss_flags = 0;
-
- if (sigaltstack(&stk, NULL) < 0) {
- fprintf(logfile, "sigaltstack returned error %d\n", errno);
- exit(1);
- }
- }
-#endif
- {
- struct sigaction act;
-
- sigfillset(&act.sa_mask);
- act.sa_flags = SA_SIGINFO;
-#if defined (TARGET_I386) && defined(USE_CODE_COPY)
- act.sa_flags |= SA_ONSTACK;
-#endif
- act.sa_sigaction = host_segv_handler;
- sigaction(SIGSEGV, &act, NULL);
- sigaction(SIGBUS, &act, NULL);
-#if defined (TARGET_I386) && defined(USE_CODE_COPY)
- sigaction(SIGFPE, &act, NULL);
-#endif
- }
-#endif
-
-#ifndef _WIN32
- {
- struct sigaction act;
- sigfillset(&act.sa_mask);
- act.sa_flags = 0;
- act.sa_handler = SIG_IGN;
- sigaction(SIGPIPE, &act, NULL);
- }
-#endif
- init_timers();
-
-#if defined(TARGET_I386)
- pc_init(ram_size, vga_ram_size, boot_device,
- ds, fd_filename, snapshot,
- kernel_filename, kernel_cmdline, initrd_filename, timeoffset);
-#elif defined(TARGET_PPC)
- ppc_init(ram_size, vga_ram_size, boot_device,
- ds, fd_filename, snapshot,
- kernel_filename, kernel_cmdline, initrd_filename);
-#elif defined(TARGET_SPARC)
- sun4m_init(ram_size, vga_ram_size, boot_device,
- ds, fd_filename, snapshot,
- kernel_filename, kernel_cmdline, initrd_filename);
-#endif
-
- gui_timer = qemu_new_timer(rt_clock, gui_update, NULL);
- qemu_mod_timer(gui_timer, qemu_get_clock(rt_clock));
-
- polling_timer = qemu_new_timer(rt_clock, polling_handler, NULL);
- qemu_mod_timer(polling_timer, qemu_get_clock(rt_clock));
-
-#ifdef CONFIG_GDBSTUB
- if (use_gdbstub) {
- if (gdbserver_start(gdbstub_port) < 0) {
- fprintf(stderr, "Could not open gdbserver socket on port %d\n",
- gdbstub_port);
- exit(1);
- } else {
- fprintf(logfile, "Waiting gdb connection on port %d\n", gdbstub_port);
- }
- } else
-#endif
- if (loadvm)
- qemu_loadvm(loadvm);
-
- {
- /* XXX: simplify init */
- if (start_emulation) {
- vm_start();
- }
- }
- main_loop();
- quit_timers();
- return 0;
-}
-
-extern fd_set wakeup_rfds;
-void tun_receive_handler(fd_set *rfds)
-{
- IOHandlerRecord *ioh;
- static uint8_t buf[4096];
- int n, max_size;
-
- for (ioh = first_eventio_handler; ioh != NULL; ioh = ioh->next) {
- if ( FD_ISSET(ioh->fd, rfds) ) {
- max_size = ioh->fd_can_read(ioh->opaque);
- if (max_size > 0) {
- if (max_size > sizeof(buf))
- max_size = sizeof(buf);
- n = read(ioh->fd, buf, max_size);
- if (n >= 0) {
- ioh->fd_read(ioh->opaque, buf, n);
- }
- }
- }
- }
- update_select_wakeup_events();
-}
-
-void update_select_wakeup_events(void)
-{
- IOHandlerRecord *ioh;
- int max_size;
-
- for(ioh = first_eventio_handler; ioh != NULL; ioh = ioh->next) {
- FD_CLR(ioh->fd, &wakeup_rfds);
- if (ioh->fd_can_read) {
- max_size = ioh->fd_can_read(ioh->opaque);
- if (max_size > 0) {
- FD_SET(ioh->fd, &wakeup_rfds);
- }
- }
- }
-}
+++ /dev/null
-/*
- * QEMU System Emulator header
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#ifndef VL_H
-#define VL_H
-
-/* we put basic includes here to avoid repeating them in device drivers */
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <string.h>
-#include <inttypes.h>
-#include <limits.h>
-#include <time.h>
-#include <ctype.h>
-#include <errno.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <sys/stat.h>
-#include "audio/audio.h"
-#include "xenctrl.h"
-#include "xs.h"
-
-#ifndef O_LARGEFILE
-#define O_LARGEFILE 0
-#endif
-#ifndef O_BINARY
-#define O_BINARY 0
-#endif
-
-#ifdef _WIN32
-#define lseek _lseeki64
-#define ENOTSUP 4096
-/* XXX: find 64 bit version */
-#define ftruncate chsize
-
-static inline char *realpath(const char *path, char *resolved_path)
-{
- _fullpath(resolved_path, path, _MAX_PATH);
- return resolved_path;
-}
-#endif
-
-#ifdef QEMU_TOOL
-
-/* we use QEMU_TOOL in the command line tools which do not depend on
- the target CPU type */
-#include "config-host.h"
-#include <setjmp.h>
-#include "osdep.h"
-#include "bswap.h"
-
-#else
-
-#include "cpu.h"
-
-#endif /* !defined(QEMU_TOOL) */
-
-#ifndef glue
-#define xglue(x, y) x ## y
-#define glue(x, y) xglue(x, y)
-#define stringify(s) tostring(s)
-#define tostring(s) #s
-#endif
-
-/* vl.c */
-uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c);
-
-void hw_error(const char *fmt, ...);
-
-int get_image_size(const char *filename);
-int load_image(const char *filename, uint8_t *addr);
-extern const char *bios_dir;
-
-void pstrcpy(char *buf, int buf_size, const char *str);
-char *pstrcat(char *buf, int buf_size, const char *s);
-int strstart(const char *str, const char *val, const char **ptr);
-
-extern int vm_running;
-
-typedef void VMStopHandler(void *opaque, int reason);
-
-int qemu_add_vm_stop_handler(VMStopHandler *cb, void *opaque);
-void qemu_del_vm_stop_handler(VMStopHandler *cb, void *opaque);
-
-void vm_start(void);
-void vm_stop(int reason);
-
-typedef void QEMUResetHandler(void *opaque);
-
-void qemu_register_reset(QEMUResetHandler *func, void *opaque);
-void qemu_system_reset_request(void);
-void qemu_system_reset(void);
-void qemu_system_shutdown_request(void);
-
-void main_loop_wait(int timeout);
-
-int unset_mm_mapping(int xc_handle,
- uint32_t domid,
- unsigned long nr_pages,
- unsigned int address_bits,
- unsigned long *extent_start);
-int set_mm_mapping(int xc_handle,
- uint32_t domid,
- unsigned long nr_pages,
- unsigned int address_bits,
- unsigned long *extent_start);
-
-extern int xc_handle;
-extern int domid;
-extern int audio_enabled;
-extern int sb16_enabled;
-extern int adlib_enabled;
-extern int gus_enabled;
-extern uint64_t ram_size;
-extern int bios_size;
-extern int rtc_utc;
-extern int cirrus_vga_enabled;
-extern int graphic_width;
-extern int graphic_height;
-extern int graphic_depth;
-
-/* XXX: make it dynamic */
-#if defined (TARGET_PPC)
-#define BIOS_SIZE (512 * 1024)
-#else
-#define BIOS_SIZE ((256 + 64) * 1024)
-#endif
-
-/* keyboard/mouse support */
-
-#define MOUSE_EVENT_LBUTTON 0x01
-#define MOUSE_EVENT_RBUTTON 0x02
-#define MOUSE_EVENT_MBUTTON 0x04
-
-typedef void QEMUPutKBDEvent(void *opaque, int keycode);
-typedef void QEMUPutMouseEvent(void *opaque, int dx, int dy, int dz, int buttons_state);
-
-void qemu_add_kbd_event_handler(QEMUPutKBDEvent *func, void *opaque);
-void qemu_add_mouse_event_handler(QEMUPutMouseEvent *func, void *opaque, int absolute);
-
-void kbd_put_keycode(int keycode);
-void kbd_mouse_event(int dx, int dy, int dz, int buttons_state);
-int kbd_mouse_is_absolute(void);
-
-/* keysym is a unicode code except for special keys (see QEMU_KEY_xxx
- constants) */
-#define QEMU_KEY_ESC1(c) ((c) | 0xe100)
-#define QEMU_KEY_BACKSPACE 0x007f
-#define QEMU_KEY_UP QEMU_KEY_ESC1('A')
-#define QEMU_KEY_DOWN QEMU_KEY_ESC1('B')
-#define QEMU_KEY_RIGHT QEMU_KEY_ESC1('C')
-#define QEMU_KEY_LEFT QEMU_KEY_ESC1('D')
-#define QEMU_KEY_HOME QEMU_KEY_ESC1(1)
-#define QEMU_KEY_END QEMU_KEY_ESC1(4)
-#define QEMU_KEY_PAGEUP QEMU_KEY_ESC1(5)
-#define QEMU_KEY_PAGEDOWN QEMU_KEY_ESC1(6)
-#define QEMU_KEY_DELETE QEMU_KEY_ESC1(3)
-
-#define QEMU_KEY_CTRL_UP 0xe400
-#define QEMU_KEY_CTRL_DOWN 0xe401
-#define QEMU_KEY_CTRL_LEFT 0xe402
-#define QEMU_KEY_CTRL_RIGHT 0xe403
-#define QEMU_KEY_CTRL_HOME 0xe404
-#define QEMU_KEY_CTRL_END 0xe405
-#define QEMU_KEY_CTRL_PAGEUP 0xe406
-#define QEMU_KEY_CTRL_PAGEDOWN 0xe407
-
-void kbd_put_keysym(int keysym);
-
-/* async I/O support */
-
-typedef void IOReadHandler(void *opaque, const uint8_t *buf, int size);
-typedef int IOCanRWHandler(void *opaque);
-
-int qemu_add_fd_read_handler(int fd, IOCanRWHandler *fd_can_read,
- IOReadHandler *fd_read, void *opaque);
-int qemu_add_fd_event_read_handler(int fd, IOCanRWHandler *fd_can_read,
- IOReadHandler *fd_read, void *opaque);
-void qemu_del_fd_read_handler(int fd);
-
-/* character device */
-
-#define CHR_EVENT_BREAK 0 /* serial break char */
-#define CHR_EVENT_FOCUS 1 /* focus to this terminal (modal input needed) */
-
-typedef void IOEventHandler(void *opaque, int event);
-
-typedef struct CharDriverState {
- int (*chr_write)(struct CharDriverState *s, const uint8_t *buf, int len);
- void (*chr_add_read_handler)(struct CharDriverState *s,
- IOCanRWHandler *fd_can_read,
- IOReadHandler *fd_read, void *opaque);
- IOEventHandler *chr_event;
- void (*chr_send_event)(struct CharDriverState *chr, int event);
- void *opaque;
-} CharDriverState;
-
-void qemu_chr_printf(CharDriverState *s, const char *fmt, ...);
-int qemu_chr_write(CharDriverState *s, const uint8_t *buf, int len);
-void qemu_chr_send_event(CharDriverState *s, int event);
-void qemu_chr_add_read_handler(CharDriverState *s,
- IOCanRWHandler *fd_can_read,
- IOReadHandler *fd_read, void *opaque);
-void qemu_chr_add_event_handler(CharDriverState *s, IOEventHandler *chr_event);
-
-/* consoles */
-
-typedef struct DisplayState DisplayState;
-typedef struct TextConsole TextConsole;
-
-extern TextConsole *vga_console;
-
-TextConsole *graphic_console_init(DisplayState *ds);
-int is_active_console(TextConsole *s);
-CharDriverState *text_console_init(DisplayState *ds);
-void console_select(unsigned int index);
-
-/* serial ports */
-
-#define MAX_SERIAL_PORTS 4
-
-extern CharDriverState *serial_hds[MAX_SERIAL_PORTS];
-extern int serial_summa_port;
-
-/* network redirectors support */
-
-#define MAX_NICS 8
-
-typedef struct NetDriverState {
- int index; /* index number in QEMU */
- uint8_t macaddr[6];
- char ifname[16];
- void (*send_packet)(struct NetDriverState *nd,
- const uint8_t *buf, int size);
- void (*add_read_packet)(struct NetDriverState *nd,
- IOCanRWHandler *fd_can_read,
- IOReadHandler *fd_read, void *opaque);
- /* tun specific data */
- int fd;
- /* slirp specific data */
-} NetDriverState;
-
-extern int nb_nics;
-extern NetDriverState nd_table[MAX_NICS];
-
-void qemu_send_packet(NetDriverState *nd, const uint8_t *buf, int size);
-void qemu_add_read_packet(NetDriverState *nd, IOCanRWHandler *fd_can_read,
- IOReadHandler *fd_read, void *opaque);
-
-/* timers */
-
-typedef struct QEMUClock QEMUClock;
-typedef struct QEMUTimer QEMUTimer;
-typedef void QEMUTimerCB(void *opaque);
-
-/* The real time clock should be used only for stuff which does not
- change the virtual machine state, as it is run even if the virtual
- machine is stopped. The real time clock has a frequency of 1000
- Hz. */
-extern QEMUClock *rt_clock;
-
-/* Rge virtual clock is only run during the emulation. It is stopped
- when the virtual machine is stopped. Virtual timers use a high
- precision clock, usually cpu cycles (use ticks_per_sec). */
-extern QEMUClock *vm_clock;
-
-int64_t qemu_get_clock(QEMUClock *clock);
-
-QEMUTimer *qemu_new_timer(QEMUClock *clock, QEMUTimerCB *cb, void *opaque);
-void qemu_free_timer(QEMUTimer *ts);
-void qemu_del_timer(QEMUTimer *ts);
-void qemu_mod_timer(QEMUTimer *ts, int64_t expire_time);
-int qemu_timer_pending(QEMUTimer *ts);
-
-extern int64_t ticks_per_sec;
-extern int pit_min_timer_count;
-
-void cpu_enable_ticks(void);
-void cpu_disable_ticks(void);
-
-/* VM Load/Save */
-
-typedef FILE QEMUFile;
-
-void qemu_put_buffer(QEMUFile *f, const uint8_t *buf, int size);
-void qemu_put_byte(QEMUFile *f, int v);
-void qemu_put_be16(QEMUFile *f, unsigned int v);
-void qemu_put_be32(QEMUFile *f, unsigned int v);
-void qemu_put_be64(QEMUFile *f, uint64_t v);
-int qemu_get_buffer(QEMUFile *f, uint8_t *buf, int size);
-int qemu_get_byte(QEMUFile *f);
-unsigned int qemu_get_be16(QEMUFile *f);
-unsigned int qemu_get_be32(QEMUFile *f);
-uint64_t qemu_get_be64(QEMUFile *f);
-
-static inline void qemu_put_be64s(QEMUFile *f, const uint64_t *pv)
-{
- qemu_put_be64(f, *pv);
-}
-
-static inline void qemu_put_be32s(QEMUFile *f, const uint32_t *pv)
-{
- qemu_put_be32(f, *pv);
-}
-
-static inline void qemu_put_be16s(QEMUFile *f, const uint16_t *pv)
-{
- qemu_put_be16(f, *pv);
-}
-
-static inline void qemu_put_8s(QEMUFile *f, const uint8_t *pv)
-{
- qemu_put_byte(f, *pv);
-}
-
-static inline void qemu_get_be64s(QEMUFile *f, uint64_t *pv)
-{
- *pv = qemu_get_be64(f);
-}
-
-static inline void qemu_get_be32s(QEMUFile *f, uint32_t *pv)
-{
- *pv = qemu_get_be32(f);
-}
-
-static inline void qemu_get_be16s(QEMUFile *f, uint16_t *pv)
-{
- *pv = qemu_get_be16(f);
-}
-
-static inline void qemu_get_8s(QEMUFile *f, uint8_t *pv)
-{
- *pv = qemu_get_byte(f);
-}
-
-int64_t qemu_ftell(QEMUFile *f);
-int64_t qemu_fseek(QEMUFile *f, int64_t pos, int whence);
-
-typedef void SaveStateHandler(QEMUFile *f, void *opaque);
-typedef int LoadStateHandler(QEMUFile *f, void *opaque, int version_id);
-
-int qemu_loadvm(const char *filename);
-int qemu_savevm(const char *filename);
-int register_savevm(const char *idstr,
- int instance_id,
- int version_id,
- SaveStateHandler *save_state,
- LoadStateHandler *load_state,
- void *opaque);
-void qemu_get_timer(QEMUFile *f, QEMUTimer *ts);
-void qemu_put_timer(QEMUFile *f, QEMUTimer *ts);
-
-/* port-e9.c */
-void port_e9_init(void);
-
-/* block.c */
-typedef struct BlockDriverState BlockDriverState;
-typedef struct BlockDriver BlockDriver;
-
-extern BlockDriver bdrv_raw;
-extern BlockDriver bdrv_cow;
-extern BlockDriver bdrv_qcow;
-extern BlockDriver bdrv_vmdk;
-extern BlockDriver bdrv_cloop;
-
-void bdrv_init(void);
-BlockDriver *bdrv_find_format(const char *format_name);
-int bdrv_create(BlockDriver *drv,
- const char *filename, int64_t size_in_sectors,
- const char *backing_file, int flags);
-BlockDriverState *bdrv_new(const char *device_name);
-void bdrv_delete(BlockDriverState *bs);
-int bdrv_open(BlockDriverState *bs, const char *filename, int snapshot);
-int bdrv_open2(BlockDriverState *bs, const char *filename, int snapshot,
- BlockDriver *drv);
-void bdrv_close(BlockDriverState *bs);
-int bdrv_read(BlockDriverState *bs, int64_t sector_num,
- uint8_t *buf, int nb_sectors);
-int bdrv_write(BlockDriverState *bs, int64_t sector_num,
- const uint8_t *buf, int nb_sectors);
-void bdrv_get_geometry(BlockDriverState *bs, int64_t *nb_sectors_ptr);
-int bdrv_commit(BlockDriverState *bs);
-void bdrv_set_boot_sector(BlockDriverState *bs, const uint8_t *data, int size);
-
-#define BDRV_TYPE_HD 0
-#define BDRV_TYPE_CDROM 1
-#define BDRV_TYPE_FLOPPY 2
-
-void bdrv_set_geometry_hint(BlockDriverState *bs,
- int cyls, int heads, int secs);
-void bdrv_set_type_hint(BlockDriverState *bs, int type);
-void bdrv_get_geometry_hint(BlockDriverState *bs,
- int *pcyls, int *pheads, int *psecs);
-int bdrv_get_type_hint(BlockDriverState *bs);
-int bdrv_is_removable(BlockDriverState *bs);
-int bdrv_is_read_only(BlockDriverState *bs);
-int bdrv_is_inserted(BlockDriverState *bs);
-int bdrv_is_locked(BlockDriverState *bs);
-void bdrv_set_locked(BlockDriverState *bs, int locked);
-void bdrv_set_change_cb(BlockDriverState *bs,
- void (*change_cb)(void *opaque), void *opaque);
-void bdrv_get_format(BlockDriverState *bs, char *buf, int buf_size);
-void bdrv_info(void);
-BlockDriverState *bdrv_find(const char *name);
-void bdrv_iterate(void (*it)(void *opaque, const char *name), void *opaque);
-int bdrv_is_encrypted(BlockDriverState *bs);
-int bdrv_set_key(BlockDriverState *bs, const char *key);
-void bdrv_iterate_format(void (*it)(void *opaque, const char *name),
- void *opaque);
-const char *bdrv_get_device_name(BlockDriverState *bs);
-
-int qcow_get_cluster_size(BlockDriverState *bs);
-int qcow_compress_cluster(BlockDriverState *bs, int64_t sector_num,
- const uint8_t *buf);
-
-#ifndef QEMU_TOOL
-/* ISA bus */
-
-extern target_phys_addr_t isa_mem_base;
-
-typedef void (IOPortWriteFunc)(void *opaque, uint32_t address, uint32_t data);
-typedef uint32_t (IOPortReadFunc)(void *opaque, uint32_t address);
-
-int register_ioport_read(int start, int length, int size,
- IOPortReadFunc *func, void *opaque);
-int register_ioport_write(int start, int length, int size,
- IOPortWriteFunc *func, void *opaque);
-void isa_unassign_ioport(int start, int length);
-
-/* PCI bus */
-
-extern int pci_enabled;
-
-extern target_phys_addr_t pci_mem_base;
-
-typedef struct PCIBus PCIBus;
-typedef struct PCIDevice PCIDevice;
-
-typedef void PCIConfigWriteFunc(PCIDevice *pci_dev,
- uint32_t address, uint32_t data, int len);
-typedef uint32_t PCIConfigReadFunc(PCIDevice *pci_dev,
- uint32_t address, int len);
-typedef void PCIMapIORegionFunc(PCIDevice *pci_dev, int region_num,
- uint32_t addr, uint32_t size, int type);
-
-#define PCI_ADDRESS_SPACE_MEM 0x00
-#define PCI_ADDRESS_SPACE_IO 0x01
-#define PCI_ADDRESS_SPACE_MEM_PREFETCH 0x08
-
-typedef struct PCIIORegion {
- uint32_t addr; /* current PCI mapping address. -1 means not mapped */
- uint32_t size;
- uint8_t type;
- PCIMapIORegionFunc *map_func;
-} PCIIORegion;
-
-#define PCI_ROM_SLOT 6
-#define PCI_NUM_REGIONS 7
-struct PCIDevice {
- /* PCI config space */
- uint8_t config[256];
-
- /* the following fields are read only */
- PCIBus *bus;
- int devfn;
- char name[64];
- PCIIORegion io_regions[PCI_NUM_REGIONS];
-
- /* do not access the following fields */
- PCIConfigReadFunc *config_read;
- PCIConfigWriteFunc *config_write;
- int irq_index;
-};
-
-PCIDevice *pci_register_device(PCIBus *bus, const char *name,
- int instance_size, int devfn,
- PCIConfigReadFunc *config_read,
- PCIConfigWriteFunc *config_write);
-
-void pci_register_io_region(PCIDevice *pci_dev, int region_num,
- uint32_t size, int type,
- PCIMapIORegionFunc *map_func);
-
-void pci_set_irq(PCIDevice *pci_dev, int irq_num, int level);
-
-uint32_t pci_default_read_config(PCIDevice *d,
- uint32_t address, int len);
-void pci_default_write_config(PCIDevice *d,
- uint32_t address, uint32_t val, int len);
-void generic_pci_save(QEMUFile* f, void *opaque);
-int generic_pci_load(QEMUFile* f, void *opaque, int version_id);
-
-extern struct PIIX3State *piix3_state;
-
-PCIBus *i440fx_init(void);
-void piix3_init(PCIBus *bus);
-void pci_bios_init(void);
-void pci_info(void);
-
-/* temporary: will be moved in platform specific file */
-PCIBus *pci_prep_init(void);
-struct openpic_t;
-void pci_pmac_set_openpic(PCIBus *bus, struct openpic_t *openpic);
-PCIBus *pci_pmac_init(void);
-
-/* openpic.c */
-typedef struct openpic_t openpic_t;
-void openpic_set_irq (openpic_t *opp, int n_IRQ, int level);
-openpic_t *openpic_init (PCIBus *bus, int *pmem_index, int nb_cpus);
-
-/* vga.c */
-
-#define VGA_RAM_SIZE (4096 * 1024)
-
-struct DisplayState {
- uint8_t *data;
- int linesize;
- int depth;
- int width;
- int height;
- void (*dpy_update)(struct DisplayState *s, int x, int y, int w, int h);
- void (*dpy_resize)(struct DisplayState *s, int w, int h);
- void (*dpy_refresh)(struct DisplayState *s);
-};
-
-static inline void dpy_update(DisplayState *s, int x, int y, int w, int h)
-{
- s->dpy_update(s, x, y, w, h);
-}
-
-static inline void dpy_resize(DisplayState *s, int w, int h)
-{
- s->dpy_resize(s, w, h);
-}
-
-int vga_initialize(PCIBus *bus, DisplayState *ds, uint8_t *vga_ram_base,
- unsigned long vga_ram_offset, int vga_ram_size);
-void vga_update_display(void);
-void vga_invalidate_display(void);
-void vga_screen_dump(const char *filename);
-
-/* vnc.c */
-void vnc_display_init(DisplayState *ds, int useAlsoSDL,
- long port, const char* connect);
-
-/* cirrus_vga.c */
-void pci_cirrus_vga_init(PCIBus *bus, DisplayState *ds, uint8_t *vga_ram_base,
- unsigned long vga_ram_offset, int vga_ram_size);
-void isa_cirrus_vga_init(DisplayState *ds, uint8_t *vga_ram_base,
- unsigned long vga_ram_offset, int vga_ram_size);
-
-/* sdl.c */
-void sdl_display_init(DisplayState *ds, int full_screen);
-
-/* ide.c */
-#define MAX_DISKS 4
-
-extern BlockDriverState *bs_table[MAX_DISKS];
-
-void isa_ide_init(int iobase, int iobase2, int irq,
- BlockDriverState *hd0, BlockDriverState *hd1);
-void pci_ide_init(PCIBus *bus, BlockDriverState **hd_table);
-void pci_piix3_ide_init(PCIBus *bus, BlockDriverState **hd_table);
-int pmac_ide_init (BlockDriverState **hd_table,
- openpic_t *openpic, int irq);
-
-/* sb16.c */
-void SB16_init (void);
-
-/* adlib.c */
-void Adlib_init (void);
-
-/* gus.c */
-void GUS_init (void);
-
-/* dma.c */
-typedef int (*DMA_transfer_handler) (void *opaque, int nchan, int pos, int size);
-int DMA_get_channel_mode (int nchan);
-int DMA_read_memory (int nchan, void *buf, int pos, int size);
-int DMA_write_memory (int nchan, void *buf, int pos, int size);
-void DMA_hold_DREQ (int nchan);
-void DMA_release_DREQ (int nchan);
-void DMA_schedule(int nchan);
-void DMA_run (void);
-void DMA_init (int high_page_enable);
-void DMA_register_channel (int nchan,
- DMA_transfer_handler transfer_handler,
- void *opaque);
-/* fdc.c */
-#define MAX_FD 2
-extern BlockDriverState *fd_table[MAX_FD];
-
-typedef struct fdctrl_t fdctrl_t;
-
-fdctrl_t *fdctrl_init (int irq_lvl, int dma_chann, int mem_mapped,
- uint32_t io_base,
- BlockDriverState **fds);
-int fdctrl_get_drive_type(fdctrl_t *fdctrl, int drive_num);
-
-/* ne2000.c */
-
-void isa_ne2000_init(int base, int irq, NetDriverState *nd);
-void pci_ne2000_init(PCIBus *bus, NetDriverState *nd);
-
-/* pcnet.c */
-
-extern int nic_ne2000;
-
-void pci_pcnet_init(PCIBus *bus, NetDriverState *nd);
-
-/* pckbd.c */
-
-void kbd_init(void);
-extern const char* keyboard_layout;
-extern int repeat_key;
-extern int usb_enabled;
-
-/* mc146818rtc.c */
-
-typedef struct RTCState RTCState;
-
-RTCState *rtc_init(int base, int irq);
-void rtc_set_memory(RTCState *s, int addr, int val);
-void rtc_set_date(RTCState *s, const struct tm *tm);
-
-/* serial.c */
-
-typedef struct SerialState SerialState;
-SerialState *serial_init(int base, int irq, CharDriverState *chr);
-void ser_queue(SerialState *s, unsigned char c);
-
-/* Mice */
-
-void summa_init(SerialState *serial, CharDriverState *chr);
-
-extern int summa_ok;
-
-/* i8259.c */
-
-void pic_set_irq(int irq, int level);
-void pic_init(void);
-uint32_t pic_intack_read(CPUState *env);
-void pic_info(void);
-void irq_info(void);
-void sp_info(void);
-int pic_irq2vec(int irq);
-
-/* i8254.c */
-
-#define PIT_FREQ 1193182
-
-typedef struct PITState PITState;
-
-PITState *pit_init(int base, int irq);
-void pit_set_gate(PITState *pit, int channel, int val);
-int pit_get_gate(PITState *pit, int channel);
-int pit_get_out(PITState *pit, int channel, int64_t current_time);
-
-/* pc.c */
-void pc_init(uint64_t ram_size, int vga_ram_size, int boot_device,
- DisplayState *ds, const char **fd_filename, int snapshot,
- const char *kernel_filename, const char *kernel_cmdline,
- const char *initrd_filename, time_t timeoffset);
-
-/* ppc.c */
-void ppc_init (int ram_size, int vga_ram_size, int boot_device,
- DisplayState *ds, const char **fd_filename, int snapshot,
- const char *kernel_filename, const char *kernel_cmdline,
- const char *initrd_filename);
-void ppc_prep_init (int ram_size, int vga_ram_size, int boot_device,
- DisplayState *ds, const char **fd_filename, int snapshot,
- const char *kernel_filename, const char *kernel_cmdline,
- const char *initrd_filename);
-void ppc_chrp_init(int ram_size, int vga_ram_size, int boot_device,
- DisplayState *ds, const char **fd_filename, int snapshot,
- const char *kernel_filename, const char *kernel_cmdline,
- const char *initrd_filename);
-#ifdef TARGET_PPC
-ppc_tb_t *cpu_ppc_tb_init (CPUState *env, uint32_t freq);
-#endif
-void PREP_debug_write (void *opaque, uint32_t addr, uint32_t val);
-
-extern CPUWriteMemoryFunc *PPC_io_write[];
-extern CPUReadMemoryFunc *PPC_io_read[];
-extern int prep_enabled;
-
-/* sun4m.c */
-void sun4m_init(int ram_size, int vga_ram_size, int boot_device,
- DisplayState *ds, const char **fd_filename, int snapshot,
- const char *kernel_filename, const char *kernel_cmdline,
- const char *initrd_filename);
-
-/* iommu.c */
-void iommu_init(uint32_t addr);
-uint32_t iommu_translate(uint32_t addr);
-
-/* lance.c */
-void lance_init(NetDriverState *nd, int irq, uint32_t leaddr, uint32_t ledaddr);
-
-/* tcx.c */
-void tcx_init(DisplayState *ds, uint32_t addr);
-
-/* sched.c */
-void sched_init(uint32_t, uint32_t);
-
-/* magic-load.c */
-void magic_init(const char *kfn, int kloadaddr, uint32_t addr);
-
-/* timer.c */
-void timer_init(uint32_t addr, int irq);
-
-/* NVRAM helpers */
-#include "hw/m48t59.h"
-
-void NVRAM_set_byte (m48t59_t *nvram, uint32_t addr, uint8_t value);
-uint8_t NVRAM_get_byte (m48t59_t *nvram, uint32_t addr);
-void NVRAM_set_word (m48t59_t *nvram, uint32_t addr, uint16_t value);
-uint16_t NVRAM_get_word (m48t59_t *nvram, uint32_t addr);
-void NVRAM_set_lword (m48t59_t *nvram, uint32_t addr, uint32_t value);
-uint32_t NVRAM_get_lword (m48t59_t *nvram, uint32_t addr);
-void NVRAM_set_string (m48t59_t *nvram, uint32_t addr,
- const unsigned char *str, uint32_t max);
-int NVRAM_get_string (m48t59_t *nvram, uint8_t *dst, uint16_t addr, int max);
-void NVRAM_set_crc (m48t59_t *nvram, uint32_t addr,
- uint32_t start, uint32_t count);
-int PPC_NVRAM_set_params (m48t59_t *nvram, uint16_t NVRAM_size,
- const unsigned char *arch,
- uint32_t RAM_size, int boot_device,
- uint32_t kernel_image, uint32_t kernel_size,
- const char *cmdline,
- uint32_t initrd_image, uint32_t initrd_size,
- uint32_t NVRAM_image,
- int width, int height, int depth);
-
-/* adb.c */
-
-#define MAX_ADB_DEVICES 16
-
-#define ADB_MAX_OUT_LEN 16
-
-typedef struct ADBDevice ADBDevice;
-
-/* buf = NULL means polling */
-typedef int ADBDeviceRequest(ADBDevice *d, uint8_t *buf_out,
- const uint8_t *buf, int len);
-typedef int ADBDeviceReset(ADBDevice *d);
-
-struct ADBDevice {
- struct ADBBusState *bus;
- int devaddr;
- int handler;
- ADBDeviceRequest *devreq;
- ADBDeviceReset *devreset;
- void *opaque;
-};
-
-typedef struct ADBBusState {
- ADBDevice devices[MAX_ADB_DEVICES];
- int nb_devices;
- int poll_index;
-} ADBBusState;
-
-int adb_request(ADBBusState *s, uint8_t *buf_out,
- const uint8_t *buf, int len);
-int adb_poll(ADBBusState *s, uint8_t *buf_out);
-
-ADBDevice *adb_register_device(ADBBusState *s, int devaddr,
- ADBDeviceRequest *devreq,
- ADBDeviceReset *devreset,
- void *opaque);
-void adb_kbd_init(ADBBusState *bus);
-void adb_mouse_init(ADBBusState *bus);
-
-/* cuda.c */
-
-#include "hw/usb.h"
-
-/* usb ports of the VM */
-
-#define MAX_VM_USB_PORTS 8
-
-extern USBPort *vm_usb_ports[MAX_VM_USB_PORTS];
-extern USBDevice *vm_usb_hub;
-
-void do_usb_add(const char *devname);
-void do_usb_del(const char *devname);
-void usb_info(void);
-
-extern ADBBusState adb_bus;
-int cuda_init(openpic_t *openpic, int irq);
-
-#endif /* defined(QEMU_TOOL) */
-
-/* monitor.c */
-void monitor_init(CharDriverState *hd, int show_banner);
-void term_puts(const char *str);
-void term_vprintf(const char *fmt, va_list ap);
-void term_printf(const char *fmt, ...) __attribute__ ((__format__ (__printf__, 1, 2)));
-void term_flush(void);
-void term_print_help(void);
-
-/* readline.c */
-typedef void ReadLineFunc(void *opaque, const char *str);
-
-extern int completion_index;
-void add_completion(const char *str);
-void readline_handle_byte(int ch);
-void readline_find_completion(const char *cmdline);
-const char *readline_get_history(unsigned int index);
-void readline_start(const char *prompt, int is_password,
- ReadLineFunc *readline_func, void *opaque);
-
-/* gdbstub.c */
-
-#define DEFAULT_GDBSTUB_PORT 1234
-
-int gdbserver_start(int port);
-void update_select_wakeup_events(void);
-void tun_receive_handler(fd_set *);
-
-extern char domain_name[];
-#endif /* VL_H */
+++ /dev/null
-/*
- * QEMU VNC display driver (uses LibVNCServer, based on QEMU SDL driver)
- *
- * Copyright (c) 2003,2004 Fabrice Bellard, Matthew Mastracci,
- * Johannes E. Schindelin
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- *
- *
- * reverse connection setup copied from x11vnc.c
- * Copyright (c) 2002-2005 Karl J. Runge <runge@karlrunge.com>
- * All rights reserved.
- * based on:
- * the originial x11vnc.c in libvncserver (Johannes E. Schindelin)
- * x0rfbserver, the original native X vnc server (Jens Wagner)
- * krfb, the KDE desktopsharing project (Tim Jansen)
- */
-#include "vl.h"
-
-#include <rfb/rfb.h>
-
-/* keyboard stuff */
-#include <rfb/keysym.h>
-#include "keysym_adapter_vnc.h"
-#include "keyboard_rdesktop.c"
-
-
-#ifndef _WIN32
-#include <signal.h>
-#endif
-
-static rfbScreenInfoPtr screen;
-static DisplayState* ds_sdl;
-static void* kbd_layout; // TODO: move into rfbClient
-static int ctl_keys; // Ctrl+Alt starts calibration
-
-/* mouse stuff */
-
-typedef struct mouse_magic_t {
- /* When calibrating, mouse_calibration contains a copy of the
- * current frame buffer. After a simulated mouse movement, the
- * update function only gets (0,y1,width,y2) as bounding box
- * of the changed region, so we refine that with the help of
- * this copy, and then update the copy. */
- char* calibration;
- /* Mouse handling using VNC used to be wrong, because if moving the
- * mouse very fast, the pointer got even faster. The reason for this:
- * when the mouse sends a delta of at least 4 (Windows: 3) pixels,
- * it is treated as if it were double the amount. I call this the
- * sonic wall. */
- int sonic_wall_x;
- int sonic_wall_y;
- /* Unfortunately, Windows and X behave differently, when the sonic
- * wall was reached in one axis, but not the other: Windows treats
- * them independently. I call this orthogonal. */
- char sonic_wall_is_orthogonal;
- /* last_dy contains the last delta sent on the y axis. We don't
- * use the x axis (see mouse_calibration). */
- //static int last_dy=0;
-} mouse_magic_t;
-
-mouse_magic_t* init_mouse_magic() {
- mouse_magic_t* ret=(mouse_magic_t*)malloc(sizeof(mouse_magic_t));
-
- ret->calibration=0;
-#ifdef EXPECT_WINDOWS_GUEST
- ret->sonic_wall_x=3;
- ret->sonic_wall_y=3;
- ret->sonic_wall_is_orthogonal=1;
-#else
- ret->sonic_wall_x=4;
- ret->sonic_wall_y=4;
- ret->sonic_wall_is_orthogonal=0;
-#endif
- return ret;
-}
-
-static void vnc_save(QEMUFile* f,void* opaque)
-{
- mouse_magic_t* s=(mouse_magic_t*)opaque;
-
- qemu_put_be32s(f, &s->sonic_wall_x);
- qemu_put_be32s(f, &s->sonic_wall_y);
- qemu_put_8s(f, &s->sonic_wall_is_orthogonal);
-}
-
-static int vnc_load(QEMUFile* f,void* opaque,int version_id)
-{
- mouse_magic_t* s=(mouse_magic_t*)opaque;
-
- if (version_id != 1)
- return -EINVAL;
-
- qemu_get_be32s(f, &s->sonic_wall_x);
- qemu_get_be32s(f, &s->sonic_wall_y);
- qemu_get_8s(f, &s->sonic_wall_is_orthogonal);
-
- return 0;
-}
-
-static mouse_magic_t* mouse_magic;
-
-typedef struct {
- int x,y,w,h;
-} rectangle_t;
-/* In order to calibrate the mouse, we have to know about the bounding boxes
- * of the last changes. */
-static rectangle_t last_update, before_update;
-static int updates_since_mouse=0;
-
-extern int mouse_maxx, mouse_maxy;
-static int mouse_x,mouse_y;
-static int new_mouse_x,new_mouse_y,new_mouse_z,new_mouse_buttons;
-
-static void init_mouse(int max_x,int max_y) {
- mouse_maxx=max_x - 1;
- mouse_maxy=max_y - 1;
- mouse_x=new_mouse_x=max_x/2;
- mouse_y=new_mouse_y=max_y/2;
- new_mouse_z=new_mouse_buttons=0;
- mouse_magic->calibration = 0;
-}
-
-static void mouse_refresh() {
- static int last_x = -1;
- static int last_y = -1;
- static int last_z = -1;
- static int last_b = -1;
- int dx=0,dy=0,dz=new_mouse_z;
- static int counter=1;
-
- if (new_mouse_x == last_x && new_mouse_y == last_y &&
- new_mouse_z == last_z && new_mouse_buttons == last_b)
- return;
- /*
- * Simulate lifting the mouse by pressing left <ctl><alt> together
- * e.g. don't send mouse events.
- */
- if (ctl_keys == 3) {
- mouse_x = new_mouse_x;
- mouse_y = new_mouse_y;
- last_x = new_mouse_x;
- last_y = new_mouse_y;
- last_z = new_mouse_z;
- last_b = new_mouse_buttons;
- return;
- }
- counter++;
- //fprintf(stderr,"sending mouse event %d,%d\n",dx,dy);
- if (kbd_mouse_is_absolute()) {
- kbd_mouse_event(new_mouse_x * 0x7FFF / screen->width,
- new_mouse_y * 0x7FFF / screen->height, dz, new_mouse_buttons);
- } else {
- if(!mouse_magic->calibration && counter>=2) { counter=0; return; }
-
- dx=new_mouse_x-last_x;
- dy=new_mouse_y-last_y;
-
- if(mouse_magic->sonic_wall_is_orthogonal) {
- if(abs(dx)>=mouse_magic->sonic_wall_x) { dx/=2; mouse_x+=dx; }
- if(abs(dy)>=mouse_magic->sonic_wall_y) { dy/=2; mouse_y+=dy; }
- } else {
- if(abs(dx)>=mouse_magic->sonic_wall_x || abs(dy)>=mouse_magic->sonic_wall_y) {
- dx/=2; mouse_x+=dx;
- dy/=2; mouse_y+=dy;
- }
- }
- if (last_x != -1)
- kbd_mouse_event(dx,dy,dz,new_mouse_buttons);
-
- }
- last_x = new_mouse_x;
- last_y = new_mouse_y;
- last_z = new_mouse_z;
- last_b = new_mouse_buttons;
-
- updates_since_mouse=0;
-}
-
-static int calibration_step=0;
-//static int calibration_count=0;
-
-static void mouse_find_bounding_box_of_difference(int* x,int* y,int* w,int* h) {
- int i,j,X=*x,Y=*y,W=*w,H=*h;
- int bpp=screen->depth/8;
-
- *x=screen->width; *w=-*x;
- *y=screen->height; *h=-*y;
- for(i=X;i<X+W;i++)
- for(j=Y;j<Y+H;j++) {
- int offset=i*bpp+j*screen->paddedWidthInBytes;
- if(memcmp(mouse_magic->calibration+offset,screen->frameBuffer+offset,bpp)) {
- if(i<((*x))) { (*w)+=(*x)-i; (*x)=i; }
- if(i>(*x)+(*w)) (*w)=i-(*x);
- if(j<(*y)) { (*h)+=(*y)-j; (*y)=j; }
- if(j>(*y)+(*h)) (*h)=j-(*y);
- }
- }
- if(h>0)
- memcpy(mouse_magic->calibration+Y*screen->paddedWidthInBytes,
- screen->frameBuffer+Y*screen->paddedWidthInBytes,
- H*screen->paddedWidthInBytes);
-}
-
-static void start_mouse_calibration() {
- int size = screen->height*screen->paddedWidthInBytes;
- free(mouse_magic->calibration);
- mouse_magic->calibration = malloc(size);
- memcpy(mouse_magic->calibration, screen->frameBuffer, size);
- calibration_step=0;
- // calibration_count=-1;
- //calibration_count=1000; updates_since_mouse=1;
- fprintf(stderr,"Starting mouse calibration:\n");
-}
-
-static void stop_mouse_calibration() {
- free(mouse_magic->calibration);
- mouse_magic->calibration = 0;
-}
-
-static void mouse_calibration_update(int x,int y,int w,int h) {
- mouse_find_bounding_box_of_difference(&x,&y,&w,&h);
- if(w<=0 || h<=0)
- return;
- last_update.x=x;
- last_update.y=y;
- last_update.w=w;
- last_update.h=h;
- updates_since_mouse++;
-}
-
-static void mouse_calibration_refresh() {
- static rectangle_t cursor;
- static int x,y;
- static int idle_counter;
-
- if(calibration_step==0)
- idle_counter=0;
- else {
- if(updates_since_mouse==0) {
- idle_counter++;
- if(idle_counter>5) {
- fprintf(stderr, "Calibration failed: no update for 5 cycles\n");
- stop_mouse_calibration();
- }
- return;
- }
- if(updates_since_mouse!=1) {
- fprintf(stderr,"Calibration failed: updates=%d\n",updates_since_mouse);
- stop_mouse_calibration();
- return;
- }
- }
-
- if(calibration_step==0) {
- x=0; y=1;
- kbd_mouse_event(0,-1,0,0);
- calibration_step++;
- } else if(calibration_step==1) {
- // find out the initial position of the cursor
- cursor=last_update;
- cursor.h--;
- calibration_step++;
- mouse_magic->sonic_wall_y=-1;
- last_update=cursor;
- x=0; y=2;
- goto move_calibrate;
- } else if(calibration_step==2) {
- // find out the sonic_wall
- if(last_update.y==before_update.y-2*y) {
- mouse_magic->sonic_wall_y=y;
- // test orthogonality
- calibration_step++;
- x=mouse_magic->sonic_wall_y+1; y=1;
- goto move_calibrate;
- } else if(last_update.y<=2) {
- if(y<6)
- fprintf(stderr,"Calibration failed: not enough head room!\n");
- else
- fprintf(stderr,"Calibration finished.\n");
- mouse_magic->sonic_wall_x=mouse_magic->sonic_wall_y=32768;
- goto stop_calibration;
- } else if(last_update.y!=before_update.y-y) {
- fprintf(stderr,"Calibration failed: delta=%d (expected: %d)\n",last_update.y-before_update.y,-y);
- goto stop_calibration;
- } else {
- y++;
-move_calibrate:
- kbd_mouse_event(-x,-y,0,0);
- before_update=last_update;
- }
- } else if(calibration_step==3) {
- if(last_update.y==before_update.y-2)
- mouse_magic->sonic_wall_is_orthogonal=0;
- else if(last_update.y==before_update.y-1)
- mouse_magic->sonic_wall_is_orthogonal=-1;
- else
- fprintf(stderr,"Calibration failed: no clue of orthogonal.\n");
- mouse_magic->sonic_wall_x=mouse_magic->sonic_wall_y;
- if(last_update.x==before_update.x-mouse_magic->sonic_wall_x)
- mouse_magic->sonic_wall_x++;
- else if(last_update.x!=before_update.x-x*2)
- fprintf(stderr,"Calibration failed: could not determine horizontal sonic wall x\n");
- fprintf(stderr,"Calibration finished\n");
-stop_calibration:
- mouse_x=last_update.x;
- mouse_y=last_update.y;
- stop_mouse_calibration();
- }
- updates_since_mouse=0;
-}
-
-/* end of mouse stuff */
-
-static void vnc_update(DisplayState *ds, int x, int y, int w, int h)
-{
- if(ds_sdl)
- ds_sdl->dpy_update(ds_sdl,x,y,w,h);
- if(0) fprintf(stderr,"updating x=%d y=%d w=%d h=%d\n", x, y, w, h);
- rfbMarkRectAsModified(screen,x,y,x+w,y+h);
- if(mouse_magic->calibration) {
- mouse_calibration_update(x,y,w,h);
- }
-}
-
-#include <SDL/SDL_video.h>
-extern SDL_PixelFormat* sdl_get_format();
-
-static void vnc_resize(DisplayState *ds, int w, int h)
-{
- int depth = screen->bitsPerPixel;
- rfbClientIteratorPtr iter;
- rfbClientPtr cl;
-
- if(w==screen->width && h==screen->height)
- return;
-
- if(ds_sdl) {
- SDL_PixelFormat* sdl_format;
- ds_sdl->dpy_resize(ds_sdl,w,h);
- ds->data = ds_sdl->data;
- ds->linesize = screen->paddedWidthInBytes = ds_sdl->linesize;
- screen->serverFormat.bitsPerPixel = screen->serverFormat.depth
- = screen->bitsPerPixel = depth = ds->depth = ds_sdl->depth;
- w = ds->width = ds_sdl->width;
- h = ds->height = ds_sdl->height;
- sdl_format=sdl_get_format();
- if(sdl_format->palette==0) {
- screen->serverFormat.trueColour=TRUE;
- screen->serverFormat.redShift=sdl_format->Rshift;
- screen->serverFormat.greenShift=sdl_format->Gshift;
- screen->serverFormat.blueShift=sdl_format->Bshift;
- screen->serverFormat.redMax=sdl_format->Rmask>>screen->serverFormat.redShift;
- screen->serverFormat.greenMax=sdl_format->Gmask>>screen->serverFormat.greenShift;
- screen->serverFormat.blueMax=sdl_format->Bmask>>screen->serverFormat.blueShift;
- } else {
- rfbColourMap* cmap=&(screen->colourMap);
- int i;
- screen->serverFormat.trueColour=FALSE;
- cmap->is16=FALSE;
- cmap->count=sdl_format->palette->ncolors;
- if(cmap->data.bytes==0)
- cmap->data.bytes=malloc(256*3);
- for(i=0;i<cmap->count;i++) {
- cmap->data.bytes[3*i+0]=sdl_format->palette->colors[i].r;
- cmap->data.bytes[3*i+1]=sdl_format->palette->colors[i].g;
- cmap->data.bytes[3*i+2]=sdl_format->palette->colors[i].b;
- }
- }
- } else {
- ds->data = (unsigned char*)realloc(ds->data, w*h*depth/8);
- ds->linesize = screen->paddedWidthInBytes = w*2;
- ds->width = w;
- ds->height = h;
- ds->depth = depth;
- screen->paddedWidthInBytes = w*depth/8;
- }
- screen->frameBuffer = ds->data;
-
- screen->width = w;
- screen->height = h;
-
- iter=rfbGetClientIterator(screen);
- while((cl=rfbClientIteratorNext(iter)))
- if(cl->useNewFBSize)
- cl->newFBSizePending = TRUE;
- else
- rfbLog("Warning: Client %s does not support NewFBSize!\n",cl->host);
- rfbReleaseClientIterator(iter);
-
- if(mouse_magic->calibration) {
- fprintf(stderr,"Warning: mouse calibration interrupted by video mode change\n");
- stop_mouse_calibration();
- }
- init_mouse(w,h);
-}
-
-static void vnc_process_key(rfbBool down, rfbKeySym keySym, rfbClientPtr cl)
-{
-
- if(is_active_console(vga_console)) {
- WORD keycode=keysym2scancode(kbd_layout, keySym);
- if(keycode>=0x80)
- keycode=(keycode<<8)^0x80e0;
- while(keycode!=0) {
- kbd_put_keycode((keycode&0xff)|(down?0:0x80));
- keycode>>=8;
- }
- } else if(down) {
- int qemu_keysym = 0;
- if (keySym <= 128) { /* normal ascii */
- qemu_keysym = keySym;
- } else {
- switch(keySym) {
- case XK_Up: qemu_keysym = QEMU_KEY_UP; break;
- case XK_Down: qemu_keysym = QEMU_KEY_DOWN; break;
- case XK_Left: qemu_keysym = QEMU_KEY_LEFT; break;
- case XK_Right: qemu_keysym = QEMU_KEY_RIGHT; break;
- case XK_Home: qemu_keysym = QEMU_KEY_HOME; break;
- case XK_End: qemu_keysym = QEMU_KEY_END; break;
- case XK_Page_Up: qemu_keysym = QEMU_KEY_PAGEUP; break;
- case XK_Page_Down: qemu_keysym = QEMU_KEY_PAGEDOWN; break;
- case XK_BackSpace: qemu_keysym = QEMU_KEY_BACKSPACE; break;
- case XK_Delete: qemu_keysym = QEMU_KEY_DELETE; break;
- case XK_Return:
- case XK_Linefeed: qemu_keysym = keySym; break;
- default: break;
- }
- }
- if (qemu_keysym != 0)
- kbd_put_keysym(qemu_keysym);
- }
- if(down) {
- if(keySym==XK_Control_L)
- ctl_keys|=1;
- else if(keySym==XK_Alt_L)
- ctl_keys|=2;
- } else {
- if (keySym == XK_Control_L)
- ctl_keys &= ~1;
- else if (keySym == XK_Alt_L)
- ctl_keys &= ~2;
- if((ctl_keys&3)==3) {
- switch(keySym) {
- case XK_Control_L:
- ctl_keys&=~1;
- break;
- case XK_Alt_L:
- ctl_keys&=~2;
- break;
- case XK_m:
- ctl_keys=0;
- start_mouse_calibration();
- break;
- case XK_1 ... XK_9:
- ctl_keys=0;
- fprintf(stderr,"switch to %d\n",keySym-XK_1);
- console_select(keySym - XK_1);
- if (is_active_console(vga_console)) {
- /* tell the vga console to redisplay itself */
- vga_invalidate_display();
- vnc_update(0,0,0,screen->width,screen->height);
- }
- break;
- }
- }
- }
-}
-
-static void vnc_process_mouse(int buttonMask, int x, int y, rfbClientPtr cl)
-{
- new_mouse_x=x; new_mouse_y=y; new_mouse_buttons=0;
- if(buttonMask&1) new_mouse_buttons|=MOUSE_EVENT_LBUTTON;
- if(buttonMask&2) new_mouse_buttons|=MOUSE_EVENT_MBUTTON;
- if(buttonMask&4) new_mouse_buttons|=MOUSE_EVENT_RBUTTON;
- if(buttonMask&8) new_mouse_z--;
- if(buttonMask&16) new_mouse_z++;
-}
-
- static void vnc_refresh(DisplayState *ds) {
- if(ds_sdl)
- ds_sdl->dpy_refresh(ds_sdl);
- else
- vga_update_display();
- rfbProcessEvents(screen,0);
- if(mouse_magic->calibration) {
- mouse_calibration_refresh();
- } else {
- mouse_refresh();
- }
- }
-
-static void vnc_cleanup(void)
-{
- rfbScreenCleanup(screen);
-}
-
-
-void vnc_display_init(DisplayState *ds, int useAlsoSDL,
- long port, const char* connect)
-{
- int len, rport = 5500;
- char host[1024];
- char *p;
- rfbClientPtr cl;
-
- summa_ok = 1;
- if(!keyboard_layout) {
- fprintf(stderr, "No keyboard language specified\n");
- exit(1);
- }
-
- kbd_layout=init_keyboard_layout(keyboard_layout);
- if(!kbd_layout) {
- fprintf(stderr, "Could not initialize keyboard\n");
- exit(1);
- }
-
-
- mouse_magic=init_mouse_magic();
- register_savevm("vnc", 0, 1, vnc_save, vnc_load, mouse_magic);
-
- rfbLog=rfbErr=term_printf;
- screen=rfbGetScreen(0,0,0,0,5,3,2);
- if(screen==0) {
- fprintf(stderr, "Could not initialize VNC - exiting\n");
- exit(1);
- }
-
-
- screen->serverFormat.redShift = 11;
- screen->serverFormat.greenShift = 5;
- screen->serverFormat.blueShift = 0;
- screen->serverFormat.redMax = 31;
- screen->serverFormat.greenMax = 63;
- screen->serverFormat.blueMax = 31;
-
-#ifdef VNC_EAGER_EVENTS
- screen->handleEventsEagerly = TRUE;
-#endif // VNC_EAGER_EVENTS
-
- if (port != 0)
- screen->port = port;
- else
- screen->autoPort = TRUE;
-
- if(useAlsoSDL) {
- ds_sdl=(DisplayState*)malloc(sizeof(DisplayState));
- sdl_display_init(ds_sdl,0);
- screen->frameBuffer = ds_sdl->data;
- } else
- screen->frameBuffer = malloc(640*400*2);
-
- screen->desktopName = domain_name;
- screen->cursor = 0;
- screen->kbdAddEvent = vnc_process_key;
- screen->ptrAddEvent = vnc_process_mouse;
- rfbInitServer(screen);
-
- vnc_resize(ds,640,400);
-
- ds->dpy_update = vnc_update;
- ds->dpy_resize = vnc_resize;
- ds->dpy_refresh = vnc_refresh;
-
- /* deal with reverse connections */
- if ( connect == NULL || (len = strlen(connect)) < 1) {
- return;
- }
- if ( len > 1024 ) {
- fprintf(stderr, "vnc reverse connect name too long\n");
- exit(1);
- }
- strncpy(host, connect, len);
- host[len] = '\0';
- /* extract port, if any */
- if ((p = strchr(host, ':')) != NULL) {
- rport = atoi(p+1);
- *p = '\0';
- }
- cl = rfbReverseConnection(screen, host, rport);
- if (cl == NULL) {
- fprintf(stderr, "reverse_connect: %s failed\n", connect);
- } else {
- fprintf(stderr, "reverse_connect: %s/%s OK\n", connect, cl->host);
- }
-
- atexit(vnc_cleanup);
-
-
-
-}
-
+++ /dev/null
-/* ld script to make i386 Linux kernel
- * Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz>;
- */
-OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
-OUTPUT_ARCH(i386)
-SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/alpha-unknown-linux-gnu/lib);
-ENTRY(_start)
-SECTIONS
-{
- /* Read-only sections, merged into text segment: */
- . = 0x60000000 + SIZEOF_HEADERS;
- .interp : { *(.interp) }
- .hash : { *(.hash) }
- .dynsym : { *(.dynsym) }
- .dynstr : { *(.dynstr) }
- .gnu.version : { *(.gnu.version) }
- .gnu.version_d : { *(.gnu.version_d) }
- .gnu.version_r : { *(.gnu.version_r) }
- .rel.text :
- { *(.rel.text) *(.rel.gnu.linkonce.t*) }
- .rela.text :
- { *(.rela.text) *(.rela.gnu.linkonce.t*) }
- .rel.data :
- { *(.rel.data) *(.rel.gnu.linkonce.d*) }
- .rela.data :
- { *(.rela.data) *(.rela.gnu.linkonce.d*) }
- .rel.rodata :
- { *(.rel.rodata) *(.rel.gnu.linkonce.r*) }
- .rela.rodata :
- { *(.rela.rodata) *(.rela.gnu.linkonce.r*) }
- .rel.got : { *(.rel.got) }
- .rela.got : { *(.rela.got) }
- .rel.ctors : { *(.rel.ctors) }
- .rela.ctors : { *(.rela.ctors) }
- .rel.dtors : { *(.rel.dtors) }
- .rela.dtors : { *(.rela.dtors) }
- .rel.init : { *(.rel.init) }
- .rela.init : { *(.rela.init) }
- .rel.fini : { *(.rel.fini) }
- .rela.fini : { *(.rela.fini) }
- .rel.bss : { *(.rel.bss) }
- .rela.bss : { *(.rela.bss) }
- .rel.plt : { *(.rel.plt) }
- .rela.plt : { *(.rela.plt) }
- .init : { *(.init) } =0x47ff041f
- .text :
- {
- *(.text)
- /* .gnu.warning sections are handled specially by elf32.em. */
- *(.gnu.warning)
- *(.gnu.linkonce.t*)
- } =0x47ff041f
- _etext = .;
- PROVIDE (etext = .);
- .fini : { *(.fini) } =0x47ff041f
- . = ALIGN(32 / 8);
- PROVIDE (__preinit_array_start = .);
- .preinit_array : { *(.preinit_array) }
- PROVIDE (__preinit_array_end = .);
- PROVIDE (__init_array_start = .);
- .init_array : { *(.init_array) }
- PROVIDE (__init_array_end = .);
- PROVIDE (__fini_array_start = .);
- .fini_array : { *(.fini_array) }
- PROVIDE (__fini_array_end = .);
- .rodata : { *(.rodata) *(.gnu.linkonce.r*) }
- .rodata1 : { *(.rodata1) }
- .reginfo : { *(.reginfo) }
- /* Adjust the address for the data segment. We want to adjust up to
- the same address within the page on the next page up. */
- . = ALIGN(0x100000) + (. & (0x100000 - 1));
- .data :
- {
- *(.data)
- *(.gnu.linkonce.d*)
- CONSTRUCTORS
- }
- .data1 : { *(.data1) }
- .ctors :
- {
- *(.ctors)
- }
- .dtors :
- {
- *(.dtors)
- }
- .plt : { *(.plt) }
- .got : { *(.got.plt) *(.got) }
- .dynamic : { *(.dynamic) }
- /* We want the small data sections together, so single-instruction offsets
- can access them all, and initialized data all before uninitialized, so
- we can shorten the on-disk segment size. */
- .sdata : { *(.sdata) }
- _edata = .;
- PROVIDE (edata = .);
- __bss_start = .;
- .sbss : { *(.sbss) *(.scommon) }
- .bss :
- {
- *(.dynbss)
- *(.bss)
- *(COMMON)
- }
- _end = . ;
- PROVIDE (end = .);
- /* Stabs debugging sections. */
- .stab 0 : { *(.stab) }
- .stabstr 0 : { *(.stabstr) }
- .stab.excl 0 : { *(.stab.excl) }
- .stab.exclstr 0 : { *(.stab.exclstr) }
- .stab.index 0 : { *(.stab.index) }
- .stab.indexstr 0 : { *(.stab.indexstr) }
- .comment 0 : { *(.comment) }
- /* DWARF debug sections.
- Symbols in the DWARF debugging sections are relative to the beginning
- of the section so we begin them at 0. */
- /* DWARF 1 */
- .debug 0 : { *(.debug) }
- .line 0 : { *(.line) }
- /* GNU DWARF 1 extensions */
- .debug_srcinfo 0 : { *(.debug_srcinfo) }
- .debug_sfnames 0 : { *(.debug_sfnames) }
- /* DWARF 1.1 and DWARF 2 */
- .debug_aranges 0 : { *(.debug_aranges) }
- .debug_pubnames 0 : { *(.debug_pubnames) }
- /* DWARF 2 */
- .debug_info 0 : { *(.debug_info) }
- .debug_abbrev 0 : { *(.debug_abbrev) }
- .debug_line 0 : { *(.debug_line) }
- .debug_frame 0 : { *(.debug_frame) }
- .debug_str 0 : { *(.debug_str) }
- .debug_loc 0 : { *(.debug_loc) }
- .debug_macinfo 0 : { *(.debug_macinfo) }
- /* SGI/MIPS DWARF 2 extensions */
- .debug_weaknames 0 : { *(.debug_weaknames) }
- .debug_funcnames 0 : { *(.debug_funcnames) }
- .debug_typenames 0 : { *(.debug_typenames) }
- .debug_varnames 0 : { *(.debug_varnames) }
- /* These must appear regardless of . */
-}
+++ /dev/null
-/* Default linker script, for normal executables */
-OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", "elf64-x86-64")
-OUTPUT_ARCH(i386:x86-64)
-ENTRY(_start)
-SEARCH_DIR("/lib64"); SEARCH_DIR("/usr/lib64"); SEARCH_DIR("/usr/local/lib64");
-SECTIONS
-{
- /* Read-only sections, merged into text segment: */
- . = 0x60000000 + SIZEOF_HEADERS;
- .interp : { *(.interp) }
- .hash : { *(.hash) }
- .dynsym : { *(.dynsym) }
- .dynstr : { *(.dynstr) }
- .gnu.version : { *(.gnu.version) }
- .gnu.version_d : { *(.gnu.version_d) }
- .gnu.version_r : { *(.gnu.version_r) }
- .rel.init : { *(.rel.init) }
- .rela.init : { *(.rela.init) }
- .rel.text : { *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*) }
- .rela.text : { *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) }
- .rel.fini : { *(.rel.fini) }
- .rela.fini : { *(.rela.fini) }
- .rel.rodata : { *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*) }
- .rela.rodata : { *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) }
- .rel.data : { *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) }
- .rela.data : { *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) }
- .rel.tdata : { *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*) }
- .rela.tdata : { *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) }
- .rel.tbss : { *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*) }
- .rela.tbss : { *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) }
- .rel.ctors : { *(.rel.ctors) }
- .rela.ctors : { *(.rela.ctors) }
- .rel.dtors : { *(.rel.dtors) }
- .rela.dtors : { *(.rela.dtors) }
- .rel.got : { *(.rel.got) }
- .rela.got : { *(.rela.got) }
- .rel.bss : { *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) }
- .rela.bss : { *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) }
- .rel.plt : { *(.rel.plt) }
- .rela.plt : { *(.rela.plt) }
- .init :
- {
- KEEP (*(.init))
- } =0x90909090
- .plt : { *(.plt) }
- .text :
- {
- *(.text .stub .text.* .gnu.linkonce.t.*)
- /* .gnu.warning sections are handled specially by elf32.em. */
- *(.gnu.warning)
- } =0x90909090
- .fini :
- {
- KEEP (*(.fini))
- } =0x90909090
- PROVIDE (__etext = .);
- PROVIDE (_etext = .);
- PROVIDE (etext = .);
- .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
- .rodata1 : { *(.rodata1) }
- .eh_frame_hdr : { *(.eh_frame_hdr) }
- .eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) }
- .gcc_except_table : ONLY_IF_RO { *(.gcc_except_table) }
- /* Adjust the address for the data segment. We want to adjust up to
- the same address within the page on the next page up. */
- . = ALIGN (0x100000) - ((0x100000 - .) & (0x100000 - 1)); . = DATA_SEGMENT_ALIGN (0x100000, 0x1000);
- /* Ensure the __preinit_array_start label is properly aligned. We
- could instead move the label definition inside the section, but
- the linker would then create the section even if it turns out to
- be empty, which isn't pretty. */
- . = ALIGN(64 / 8);
- PROVIDE (__preinit_array_start = .);
- .preinit_array : { *(.preinit_array) }
- PROVIDE (__preinit_array_end = .);
- PROVIDE (__init_array_start = .);
- .init_array : { *(.init_array) }
- PROVIDE (__init_array_end = .);
- PROVIDE (__fini_array_start = .);
- .fini_array : { *(.fini_array) }
- PROVIDE (__fini_array_end = .);
- .data :
- {
- *(.data .data.* .gnu.linkonce.d.*)
- SORT(CONSTRUCTORS)
- }
- .data1 : { *(.data1) }
- .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) }
- .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
- .eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) }
- .gcc_except_table : ONLY_IF_RW { *(.gcc_except_table) }
- .dynamic : { *(.dynamic) }
- .ctors :
- {
- /* gcc uses crtbegin.o to find the start of
- the constructors, so we make sure it is
- first. Because this is a wildcard, it
- doesn't matter if the user does not
- actually link against crtbegin.o; the
- linker won't look for a file to match a
- wildcard. The wildcard also means that it
- doesn't matter which directory crtbegin.o
- is in. */
- KEEP (*crtbegin.o(.ctors))
- /* We don't want to include the .ctor section from
- from the crtend.o file until after the sorted ctors.
- The .ctor section from the crtend file contains the
- end of ctors marker and it must be last */
- KEEP (*(EXCLUDE_FILE (*crtend.o ) .ctors))
- KEEP (*(SORT(.ctors.*)))
- KEEP (*(.ctors))
- }
- .dtors :
- {
- KEEP (*crtbegin.o(.dtors))
- KEEP (*(EXCLUDE_FILE (*crtend.o ) .dtors))
- KEEP (*(SORT(.dtors.*)))
- KEEP (*(.dtors))
- }
- .jcr : { KEEP (*(.jcr)) }
- .got : { *(.got.plt) *(.got) }
- _edata = .;
- PROVIDE (edata = .);
- __bss_start = .;
- .bss :
- {
- *(.dynbss)
- *(.bss .bss.* .gnu.linkonce.b.*)
- *(COMMON)
- /* Align here to ensure that the .bss section occupies space up to
- _end. Align after .bss to ensure correct alignment even if the
- .bss section disappears because there are no input sections. */
- . = ALIGN(64 / 8);
- }
- . = ALIGN(64 / 8);
- _end = .;
- PROVIDE (end = .);
- . = DATA_SEGMENT_END (.);
- /* Stabs debugging sections. */
- .stab 0 : { *(.stab) }
- .stabstr 0 : { *(.stabstr) }
- .stab.excl 0 : { *(.stab.excl) }
- .stab.exclstr 0 : { *(.stab.exclstr) }
- .stab.index 0 : { *(.stab.index) }
- .stab.indexstr 0 : { *(.stab.indexstr) }
- .comment 0 : { *(.comment) }
- /* DWARF debug sections.
- Symbols in the DWARF debugging sections are relative to the beginning
- of the section so we begin them at 0. */
- /* DWARF 1 */
- .debug 0 : { *(.debug) }
- .line 0 : { *(.line) }
- /* GNU DWARF 1 extensions */
- .debug_srcinfo 0 : { *(.debug_srcinfo) }
- .debug_sfnames 0 : { *(.debug_sfnames) }
- /* DWARF 1.1 and DWARF 2 */
- .debug_aranges 0 : { *(.debug_aranges) }
- .debug_pubnames 0 : { *(.debug_pubnames) }
- /* DWARF 2 */
- .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
- .debug_abbrev 0 : { *(.debug_abbrev) }
- .debug_line 0 : { *(.debug_line) }
- .debug_frame 0 : { *(.debug_frame) }
- .debug_str 0 : { *(.debug_str) }
- .debug_loc 0 : { *(.debug_loc) }
- .debug_macinfo 0 : { *(.debug_macinfo) }
- /* SGI/MIPS DWARF 2 extensions */
- .debug_weaknames 0 : { *(.debug_weaknames) }
- .debug_funcnames 0 : { *(.debug_funcnames) }
- .debug_typenames 0 : { *(.debug_typenames) }
- .debug_varnames 0 : { *(.debug_varnames) }
-}